aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs29
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs534
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs103
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs592
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs571
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
14 files changed, 1309 insertions, 752 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 7307662..fd7d44f 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
53 { 53 {
54 get { return m_movementAnimation; } 54 get { return m_movementAnimation; }
55 } 55 }
56 protected string m_movementAnimation = "DEFAULT"; 56 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
57 57 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
58 private int m_animTickFall; 58 private int m_animTickFall;
59 private int m_animTickJump; 59 private int m_animTickJump;
60 60
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
123 /// </summary> 123 /// </summary>
124 public void TrySetMovementAnimation(string anim) 124 public void TrySetMovementAnimation(string anim)
125 { 125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim); 126//Console.WriteLine("Updating movement animation to {0}", anim);
127 127
128 if (!m_scenePresence.IsChildAgent) 128 if (!m_scenePresence.IsChildAgent)
129 { 129 {
130 if (m_animations.TrySetDefaultAnimation( 130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
132 { 132 {
133//Console.WriteLine("TSMA {0} success.", anim);
133 // 16384 is CHANGED_ANIMATION 134 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); 135 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack(); 136 SendAnimPack();
136 } 137 }
138 else
139 {
140//Console.WriteLine("TSMA {0} fail.", anim);
141 }
137 } 142 }
138 } 143 }
139 144
@@ -146,10 +151,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
146 const float PREJUMP_DELAY = 0.25f; 151 const float PREJUMP_DELAY = 0.25f;
147 152
148 #region Inputs 153 #region Inputs
149 if (m_scenePresence.SitGround) 154
150 {
151 return "SIT_GROUND_CONSTRAINED";
152 }
153 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; 155 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
154 PhysicsActor actor = m_scenePresence.PhysicsActor; 156 PhysicsActor actor = m_scenePresence.PhysicsActor;
155 157
@@ -159,11 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
159 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
160 162
161 // Check control flags 163 // Check control flags
162 bool heldForward = 164 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
163 (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); 165 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
164 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 166 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
165 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 167 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
166 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
167 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 168 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
168 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 169 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
169 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 170 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -316,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
316 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
317 { 318 {
318 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
319 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
320 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
321 { 322 {
322 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -451,4 +452,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
451 m_scenePresence = null; 452 m_scenePresence = null;
452 } 453 }
453 } 454 }
454} \ No newline at end of file 455}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index ac04462..3cce53d 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -206,7 +206,11 @@ namespace OpenSim.Region.Framework.Scenes
206 public event OnMakeChildAgentDelegate OnMakeChildAgent; 206 public event OnMakeChildAgentDelegate OnMakeChildAgent;
207 207
208 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 208 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
209 public delegate void OnSaveNewWindlightProfileDelegate();
210 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
209 public event OnMakeRootAgentDelegate OnMakeRootAgent; 211 public event OnMakeRootAgentDelegate OnMakeRootAgent;
212 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
213 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
210 214
211 /// <summary> 215 /// <summary>
212 /// Triggered when an object or attachment enters a scene 216 /// Triggered when an object or attachment enters a scene
@@ -1216,6 +1220,24 @@ namespace OpenSim.Region.Framework.Scenes
1216 } 1220 }
1217 } 1221 }
1218 1222
1223 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
1224 {
1225 OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
1226 if (handlerSendNewWindlightProfileTargeted != null)
1227 {
1228 handlerSendNewWindlightProfileTargeted(wl, user);
1229 }
1230 }
1231
1232 public void TriggerOnSaveNewWindlightProfile()
1233 {
1234 OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
1235 if (handlerSaveNewWindlightProfile != null)
1236 {
1237 handlerSaveNewWindlightProfile();
1238 }
1239 }
1240
1219 public void TriggerOnMakeRootAgent(ScenePresence presence) 1241 public void TriggerOnMakeRootAgent(ScenePresence presence)
1220 { 1242 {
1221 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent; 1243 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent;
@@ -1992,4 +2014,4 @@ namespace OpenSim.Region.Framework.Scenes
1992 } 2014 }
1993 } 2015 }
1994 } 2016 }
1995} \ No newline at end of file 2017}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 6df25d6..e458ecf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -782,8 +782,12 @@ namespace OpenSim.Region.Framework.Scenes
782 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 782 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
783 { 783 {
784 SceneObjectPart part = GetSceneObjectPart(localID); 784 SceneObjectPart part = GetSceneObjectPart(localID);
785 SceneObjectGroup group = part.ParentGroup; 785 SceneObjectGroup group = null;
786 if (group != null) 786 if (part != null)
787 {
788 group = part.ParentGroup;
789 }
790 if (part != null && group != null)
787 { 791 {
788 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 792 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
789 if (item == null) 793 if (item == null)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5e5a52e..181b7c5 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -601,6 +601,8 @@ namespace OpenSim.Region.Framework.Scenes
601 601
602 // Load region settings 602 // Load region settings
603 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 603 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
604 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
605
604 if (m_storageManager.EstateDataStore != null) 606 if (m_storageManager.EstateDataStore != null)
605 { 607 {
606 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); 608 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
@@ -979,6 +981,15 @@ namespace OpenSim.Region.Framework.Scenes
979 /// <param name="seconds">float indicating duration before restart.</param> 981 /// <param name="seconds">float indicating duration before restart.</param>
980 public virtual void Restart(float seconds) 982 public virtual void Restart(float seconds)
981 { 983 {
984 Restart(seconds, true);
985 }
986
987 /// <summary>
988 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
989 /// </summary>
990 /// <param name="seconds">float indicating duration before restart.</param>
991 public virtual void Restart(float seconds, bool showDialog)
992 {
982 // notifications are done in 15 second increments 993 // notifications are done in 15 second increments
983 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 994 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
984 // It's a 'Cancel restart' request. 995 // It's a 'Cancel restart' request.
@@ -999,8 +1010,11 @@ namespace OpenSim.Region.Framework.Scenes
999 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 1010 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
1000 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 1011 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
1001 m_restartTimer.Start(); 1012 m_restartTimer.Start();
1002 m_dialogModule.SendNotificationToUsersInRegion( 1013 if (showDialog)
1014 {
1015 m_dialogModule.SendNotificationToUsersInRegion(
1003 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0))); 1016 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
1017 }
1004 } 1018 }
1005 } 1019 }
1006 1020
@@ -1280,16 +1294,16 @@ namespace OpenSim.Region.Framework.Scenes
1280 // Check if any objects have reached their targets 1294 // Check if any objects have reached their targets
1281 CheckAtTargets(); 1295 CheckAtTargets();
1282 1296
1283 // Update SceneObjectGroups that have scheduled themselves for updates
1284 // Objects queue their updates onto all scene presences
1285 if (m_frame % m_update_objects == 0)
1286 m_sceneGraph.UpdateObjectGroups();
1287
1288 // Run through all ScenePresences looking for updates 1297 // Run through all ScenePresences looking for updates
1289 // Presence updates and queued object updates for each presence are sent to clients 1298 // Presence updates and queued object updates for each presence are sent to clients
1290 if (m_frame % m_update_presences == 0) 1299 if (m_frame % m_update_presences == 0)
1291 m_sceneGraph.UpdatePresences(); 1300 m_sceneGraph.UpdatePresences();
1292 1301
1302 // Update SceneObjectGroups that have scheduled themselves for updates
1303 // Objects queue their updates onto all scene presences
1304 if (m_frame % m_update_objects == 0)
1305 m_sceneGraph.UpdateObjectGroups();
1306
1293 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1307 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1294 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1308 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1295 m_sceneGraph.UpdatePreparePhysics(); 1309 m_sceneGraph.UpdatePreparePhysics();
@@ -1600,6 +1614,19 @@ namespace OpenSim.Region.Framework.Scenes
1600 public void SaveTerrain() 1614 public void SaveTerrain()
1601 { 1615 {
1602 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1616 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1617 }
1618
1619 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1620 {
1621 m_regInfo.WindlightSettings = wl;
1622 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1623 m_eventManager.TriggerOnSaveNewWindlightProfile();
1624 }
1625
1626 public void LoadWindlightProfile()
1627 {
1628 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1629 m_eventManager.TriggerOnSaveNewWindlightProfile();
1603 } 1630 }
1604 1631
1605 /// <summary> 1632 /// <summary>
@@ -3244,6 +3271,9 @@ namespace OpenSim.Region.Framework.Scenes
3244 3271
3245 CapsModule.AddCapsHandler(agent.AgentID); 3272 CapsModule.AddCapsHandler(agent.AgentID);
3246 3273
3274 if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
3275 System.Threading.Thread.Sleep(2000);
3276
3247 if (!agent.child) 3277 if (!agent.child)
3248 { 3278 {
3249 if (TestBorderCross(agent.startpos,Cardinals.E)) 3279 if (TestBorderCross(agent.startpos,Cardinals.E))
@@ -3302,6 +3332,7 @@ namespace OpenSim.Region.Framework.Scenes
3302 } 3332 }
3303 } 3333 }
3304 // Honor parcel landing type and position. 3334 // Honor parcel landing type and position.
3335 /*
3305 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3336 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3306 if (land != null) 3337 if (land != null)
3307 { 3338 {
@@ -3310,6 +3341,7 @@ namespace OpenSim.Region.Framework.Scenes
3310 agent.startpos = land.LandData.UserLocation; 3341 agent.startpos = land.LandData.UserLocation;
3311 } 3342 }
3312 } 3343 }
3344 */// This is now handled properly in ScenePresence.MakeRootAgent
3313 } 3345 }
3314 3346
3315 agent.teleportFlags = teleportFlags; 3347 agent.teleportFlags = teleportFlags;
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index e87f7ca..8a74d7b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -300,7 +300,7 @@ namespace OpenSim.Region.Framework.Scenes
300 d); 300 d);
301 } 301 }
302 } 302 }
303 303
304 public List<GridRegion> RequestNamedRegions(string name, int maxNumber) 304 public List<GridRegion> RequestNamedRegions(string name, int maxNumber)
305 { 305 {
306 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber); 306 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 369552f..928dc97 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -223,6 +223,30 @@ namespace OpenSim.Region.Framework.Scenes
223 protected internal bool AddRestoredSceneObject( 223 protected internal bool AddRestoredSceneObject(
224 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) 224 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
225 { 225 {
226 // KF: Check for out-of-region, move inside and make static.
227 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
228 sceneObject.RootPart.GroupPosition.Y,
229 sceneObject.RootPart.GroupPosition.Z);
230 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 ||
231 npos.X > Constants.RegionSize ||
232 npos.Y > Constants.RegionSize))
233 {
234 if (npos.X < 0.0) npos.X = 1.0f;
235 if (npos.Y < 0.0) npos.Y = 1.0f;
236 if (npos.Z < 0.0) npos.Z = 0.0f;
237 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
238 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
239
240 foreach (SceneObjectPart part in sceneObject.Children.Values)
241 {
242 part.GroupPosition = npos;
243 }
244 sceneObject.RootPart.Velocity = Vector3.Zero;
245 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
246 sceneObject.RootPart.Acceleration = Vector3.Zero;
247 sceneObject.RootPart.Velocity = Vector3.Zero;
248 }
249
226 if (!alreadyPersisted) 250 if (!alreadyPersisted)
227 { 251 {
228 sceneObject.ForceInventoryPersistence(); 252 sceneObject.ForceInventoryPersistence();
@@ -567,6 +591,18 @@ namespace OpenSim.Region.Framework.Scenes
567 if (group.GetFromItemID() == itemID) 591 if (group.GetFromItemID() == itemID)
568 { 592 {
569 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); 593 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
594 bool hasScripts = false;
595 foreach (SceneObjectPart part in group.Children.Values)
596 {
597 if (part.Inventory.ContainsScripts())
598 {
599 hasScripts = true;
600 break;
601 }
602 }
603
604 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
605 System.Threading.Thread.Sleep(100);
570 group.DetachToInventoryPrep(); 606 group.DetachToInventoryPrep();
571 m_log.Debug("[DETACH]: Saving attachpoint: " + 607 m_log.Debug("[DETACH]: Saving attachpoint: " +
572 ((uint)group.GetAttachmentPoint()).ToString()); 608 ((uint)group.GetAttachmentPoint()).ToString());
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 71354b4..8b58b3e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -46,12 +46,12 @@ namespace OpenSim.Region.Framework.Scenes
46 /// </summary> 46 /// </summary>
47 public void ForceInventoryPersistence() 47 public void ForceInventoryPersistence()
48 { 48 {
49 lock (m_parts) 49 lockPartsForRead(true);
50 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
51 lockPartsForRead(false);
52 foreach (SceneObjectPart part in values)
50 { 53 {
51 foreach (SceneObjectPart part in m_parts.Values) 54 part.Inventory.ForceInventoryPersistence();
52 {
53 part.Inventory.ForceInventoryPersistence();
54 }
55 } 55 }
56 } 56 }
57 57
@@ -74,19 +74,17 @@ namespace OpenSim.Region.Framework.Scenes
74 /// <summary> 74 /// <summary>
75 /// Stop the scripts contained in all the prims in this group 75 /// Stop the scripts contained in all the prims in this group
76 /// </summary> 76 /// </summary>
77 /// <param name="sceneObjectBeingDeleted">
78 /// Should be true if these scripts are being removed because the scene
79 /// object is being deleted. This will prevent spurious updates to the client.
80 /// </param>
81 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 77 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
82 { 78 {
83 lock (m_parts) 79 lockPartsForRead(true);
80 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
81 lockPartsForRead(false);
82
83 foreach (SceneObjectPart part in values)
84 { 84 {
85 foreach (SceneObjectPart part in m_parts.Values) 85 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
86 {
87 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
88 }
89 } 86 }
87
90 } 88 }
91 89
92 /// <summary> 90 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index c5a6171..2a4e5a2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -106,6 +106,72 @@ namespace OpenSim.Region.Framework.Scenes
106 private bool m_hasGroupChanged = false; 106 private bool m_hasGroupChanged = false;
107 private long timeFirstChanged; 107 private long timeFirstChanged;
108 private long timeLastChanged; 108 private long timeLastChanged;
109 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
110
111 public void lockPartsForRead(bool locked)
112 {
113 if (locked)
114 {
115 if (m_partsLock.RecursiveReadCount > 0)
116 {
117 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
118 m_partsLock.ExitReadLock();
119 }
120 if (m_partsLock.RecursiveWriteCount > 0)
121 {
122 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
123 m_partsLock.ExitWriteLock();
124 }
125
126 while (!m_partsLock.TryEnterReadLock(60000))
127 {
128 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
129 if (m_partsLock.IsWriteLockHeld)
130 {
131 m_partsLock = new System.Threading.ReaderWriterLockSlim();
132 }
133 }
134 }
135 else
136 {
137 if (m_partsLock.RecursiveReadCount > 0)
138 {
139 m_partsLock.ExitReadLock();
140 }
141 }
142 }
143 public void lockPartsForWrite(bool locked)
144 {
145 if (locked)
146 {
147 if (m_partsLock.RecursiveReadCount > 0)
148 {
149 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
150 m_partsLock.ExitReadLock();
151 }
152 if (m_partsLock.RecursiveWriteCount > 0)
153 {
154 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
155 m_partsLock.ExitWriteLock();
156 }
157
158 while (!m_partsLock.TryEnterWriteLock(60000))
159 {
160 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
161 if (m_partsLock.IsWriteLockHeld)
162 {
163 m_partsLock = new System.Threading.ReaderWriterLockSlim();
164 }
165 }
166 }
167 else
168 {
169 if (m_partsLock.RecursiveWriteCount > 0)
170 {
171 m_partsLock.ExitWriteLock();
172 }
173 }
174 }
109 175
110 public bool HasGroupChanged 176 public bool HasGroupChanged
111 { 177 {
@@ -258,13 +324,16 @@ namespace OpenSim.Region.Framework.Scenes
258 set 324 set
259 { 325 {
260 m_regionHandle = value; 326 m_regionHandle = value;
261 lock (m_parts) 327 lockPartsForRead(true);
262 { 328 {
263 foreach (SceneObjectPart part in m_parts.Values) 329 foreach (SceneObjectPart part in m_parts.Values)
264 { 330 {
331
265 part.RegionHandle = m_regionHandle; 332 part.RegionHandle = m_regionHandle;
333
266 } 334 }
267 } 335 }
336 lockPartsForRead(false);
268 } 337 }
269 } 338 }
270 339
@@ -298,6 +367,9 @@ namespace OpenSim.Region.Framework.Scenes
298 { 367 {
299 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 368 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
300 } 369 }
370
371 lockPartsForRead(true);
372
301 if (RootPart.GetStatusSandbox()) 373 if (RootPart.GetStatusSandbox())
302 { 374 {
303 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 375 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -305,16 +377,15 @@ namespace OpenSim.Region.Framework.Scenes
305 RootPart.ScriptSetPhysicsStatus(false); 377 RootPart.ScriptSetPhysicsStatus(false);
306 Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), 378 Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"),
307 ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); 379 ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false);
380 lockPartsForRead(false);
308 return; 381 return;
309 } 382 }
310 } 383 }
311 lock (m_parts) 384
312 { 385 foreach (SceneObjectPart part in m_parts.Values)
313 foreach (SceneObjectPart part in m_parts.Values) 386 part.GroupPosition = val;
314 { 387
315 part.GroupPosition = val; 388 lockPartsForRead(false);
316 }
317 }
318 389
319 //if (m_rootPart.PhysActor != null) 390 //if (m_rootPart.PhysActor != null)
320 //{ 391 //{
@@ -504,13 +575,16 @@ namespace OpenSim.Region.Framework.Scenes
504 575
505 public void SetFromItemID(UUID AssetId) 576 public void SetFromItemID(UUID AssetId)
506 { 577 {
507 lock (m_parts) 578 lockPartsForRead(true);
508 { 579 {
509 foreach (SceneObjectPart part in m_parts.Values) 580 foreach (SceneObjectPart part in m_parts.Values)
510 { 581 {
582
511 part.FromItemID = AssetId; 583 part.FromItemID = AssetId;
584
512 } 585 }
513 } 586 }
587 lockPartsForRead(false);
514 } 588 }
515 589
516 public UUID GetFromItemID() 590 public UUID GetFromItemID()
@@ -577,10 +651,11 @@ namespace OpenSim.Region.Framework.Scenes
577 Vector3 maxScale = Vector3.Zero; 651 Vector3 maxScale = Vector3.Zero;
578 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 652 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
579 653
580 lock (m_parts) 654 lockPartsForRead(true);
581 { 655 {
582 foreach (SceneObjectPart part in m_parts.Values) 656 foreach (SceneObjectPart part in m_parts.Values)
583 { 657 {
658
584 Vector3 partscale = part.Scale; 659 Vector3 partscale = part.Scale;
585 Vector3 partoffset = part.OffsetPosition; 660 Vector3 partoffset = part.OffsetPosition;
586 661
@@ -591,8 +666,11 @@ namespace OpenSim.Region.Framework.Scenes
591 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 666 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
592 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 667 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
593 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 668 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
669
594 } 670 }
595 } 671 }
672 lockPartsForRead(false);
673
596 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 674 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
597 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 675 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
598 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 676 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -608,10 +686,11 @@ namespace OpenSim.Region.Framework.Scenes
608 686
609 EntityIntersection result = new EntityIntersection(); 687 EntityIntersection result = new EntityIntersection();
610 688
611 lock (m_parts) 689 lockPartsForRead(true);
612 { 690 {
613 foreach (SceneObjectPart part in m_parts.Values) 691 foreach (SceneObjectPart part in m_parts.Values)
614 { 692 {
693
615 // Temporary commented to stop compiler warning 694 // Temporary commented to stop compiler warning
616 //Vector3 partPosition = 695 //Vector3 partPosition =
617 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 696 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -639,8 +718,10 @@ namespace OpenSim.Region.Framework.Scenes
639 result.distance = inter.distance; 718 result.distance = inter.distance;
640 } 719 }
641 } 720 }
721
642 } 722 }
643 } 723 }
724 lockPartsForRead(false);
644 return result; 725 return result;
645 } 726 }
646 727
@@ -653,10 +734,11 @@ namespace OpenSim.Region.Framework.Scenes
653 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 734 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
654 { 735 {
655 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 736 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
656 lock (m_parts) 737 lockPartsForRead(true);
657 { 738 {
658 foreach (SceneObjectPart part in m_parts.Values) 739 foreach (SceneObjectPart part in m_parts.Values)
659 { 740 {
741
660 Vector3 worldPos = part.GetWorldPosition(); 742 Vector3 worldPos = part.GetWorldPosition();
661 Vector3 offset = worldPos - AbsolutePosition; 743 Vector3 offset = worldPos - AbsolutePosition;
662 Quaternion worldRot; 744 Quaternion worldRot;
@@ -715,6 +797,8 @@ namespace OpenSim.Region.Framework.Scenes
715 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 797 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
716 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 798 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
717 799
800
801
718 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 802 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
719 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 803 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
720 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 804 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -886,6 +970,7 @@ namespace OpenSim.Region.Framework.Scenes
886 minZ = backBottomLeft.Z; 970 minZ = backBottomLeft.Z;
887 } 971 }
888 } 972 }
973 lockPartsForRead(false);
889 974
890 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 975 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
891 976
@@ -914,17 +999,20 @@ namespace OpenSim.Region.Framework.Scenes
914 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 999 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
915 1000
916 // Capture script state while holding the lock 1001 // Capture script state while holding the lock
917 lock (m_parts) 1002 lockPartsForRead(true);
918 { 1003 {
919 foreach (SceneObjectPart part in m_parts.Values) 1004 foreach (SceneObjectPart part in m_parts.Values)
920 { 1005 {
1006
921 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 1007 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
922 foreach (UUID itemid in pstates.Keys) 1008 foreach (UUID itemid in pstates.Keys)
923 { 1009 {
924 states.Add(itemid, pstates[itemid]); 1010 states.Add(itemid, pstates[itemid]);
925 } 1011 }
1012
926 } 1013 }
927 } 1014 }
1015 lockPartsForRead(false);
928 1016
929 if (states.Count > 0) 1017 if (states.Count > 0)
930 { 1018 {
@@ -1086,13 +1174,16 @@ namespace OpenSim.Region.Framework.Scenes
1086 1174
1087 public override void UpdateMovement() 1175 public override void UpdateMovement()
1088 { 1176 {
1089 lock (m_parts) 1177 lockPartsForRead(true);
1090 { 1178 {
1091 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1092 { 1180 {
1181
1093 part.UpdateMovement(); 1182 part.UpdateMovement();
1183
1094 } 1184 }
1095 } 1185 }
1186 lockPartsForRead(false);
1096 } 1187 }
1097 1188
1098 public ushort GetTimeDilation() 1189 public ushort GetTimeDilation()
@@ -1136,7 +1227,7 @@ namespace OpenSim.Region.Framework.Scenes
1136 /// <param name="part"></param> 1227 /// <param name="part"></param>
1137 public void AddPart(SceneObjectPart part) 1228 public void AddPart(SceneObjectPart part)
1138 { 1229 {
1139 lock (m_parts) 1230 lockPartsForWrite(true);
1140 { 1231 {
1141 part.SetParent(this); 1232 part.SetParent(this);
1142 m_parts.Add(part.UUID, part); 1233 m_parts.Add(part.UUID, part);
@@ -1146,6 +1237,7 @@ namespace OpenSim.Region.Framework.Scenes
1146 if (part.LinkNum == 2 && RootPart != null) 1237 if (part.LinkNum == 2 && RootPart != null)
1147 RootPart.LinkNum = 1; 1238 RootPart.LinkNum = 1;
1148 } 1239 }
1240 lockPartsForWrite(false);
1149 } 1241 }
1150 1242
1151 /// <summary> 1243 /// <summary>
@@ -1153,28 +1245,33 @@ namespace OpenSim.Region.Framework.Scenes
1153 /// </summary> 1245 /// </summary>
1154 private void UpdateParentIDs() 1246 private void UpdateParentIDs()
1155 { 1247 {
1156 lock (m_parts) 1248 lockPartsForRead(true);
1157 { 1249 {
1158 foreach (SceneObjectPart part in m_parts.Values) 1250 foreach (SceneObjectPart part in m_parts.Values)
1159 { 1251 {
1252
1160 if (part.UUID != m_rootPart.UUID) 1253 if (part.UUID != m_rootPart.UUID)
1161 { 1254 {
1162 part.ParentID = m_rootPart.LocalId; 1255 part.ParentID = m_rootPart.LocalId;
1163 } 1256 }
1257
1164 } 1258 }
1165 } 1259 }
1260 lockPartsForRead(false);
1166 } 1261 }
1167 1262
1168 public void RegenerateFullIDs() 1263 public void RegenerateFullIDs()
1169 { 1264 {
1170 lock (m_parts) 1265 lockPartsForRead(true);
1171 { 1266 {
1172 foreach (SceneObjectPart part in m_parts.Values) 1267 foreach (SceneObjectPart part in m_parts.Values)
1173 { 1268 {
1269
1174 part.UUID = UUID.Random(); 1270 part.UUID = UUID.Random();
1175 1271
1176 } 1272 }
1177 } 1273 }
1274 lockPartsForRead(false);
1178 } 1275 }
1179 1276
1180 // helper provided for parts. 1277 // helper provided for parts.
@@ -1255,29 +1352,33 @@ namespace OpenSim.Region.Framework.Scenes
1255 1352
1256 DetachFromBackup(); 1353 DetachFromBackup();
1257 1354
1258 lock (m_parts) 1355 lockPartsForRead(true);
1356 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1357 lockPartsForRead(false);
1358
1359 foreach (SceneObjectPart part in values)
1259 { 1360 {
1260 foreach (SceneObjectPart part in m_parts.Values)
1261 {
1262// part.Inventory.RemoveScriptInstances(); 1361// part.Inventory.RemoveScriptInstances();
1263 1362
1264 ScenePresence[] avatars = Scene.GetScenePresences(); 1363 ScenePresence[] avatars = Scene.GetScenePresences();
1265 for (int i = 0; i < avatars.Length; i++) 1364 for (int i = 0; i < avatars.Length; i++)
1365 {
1366 if (avatars[i].ParentID == LocalId)
1266 { 1367 {
1267 if (avatars[i].ParentID == LocalId) 1368 avatars[i].StandUp();
1268 { 1369 }
1269 avatars[i].StandUp();
1270 }
1271 1370
1272 if (!silent) 1371 if (!silent)
1273 { 1372 {
1274 part.UpdateFlag = 0; 1373 part.UpdateFlag = 0;
1275 if (part == m_rootPart) 1374 if (part == m_rootPart)
1276 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1375 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1277 }
1278 } 1376 }
1279 } 1377 }
1378
1280 } 1379 }
1380
1381
1281 } 1382 }
1282 1383
1283 public void AddScriptLPS(int count) 1384 public void AddScriptLPS(int count)
@@ -1302,17 +1403,20 @@ namespace OpenSim.Region.Framework.Scenes
1302 1403
1303 scriptEvents aggregateScriptEvents=0; 1404 scriptEvents aggregateScriptEvents=0;
1304 1405
1305 lock (m_parts) 1406 lockPartsForRead(true);
1306 { 1407 {
1307 foreach (SceneObjectPart part in m_parts.Values) 1408 foreach (SceneObjectPart part in m_parts.Values)
1308 { 1409 {
1410
1309 if (part == null) 1411 if (part == null)
1310 continue; 1412 continue;
1311 if (part != RootPart) 1413 if (part != RootPart)
1312 part.ObjectFlags = objectflagupdate; 1414 part.ObjectFlags = objectflagupdate;
1313 aggregateScriptEvents |= part.AggregateScriptEvents; 1415 aggregateScriptEvents |= part.AggregateScriptEvents;
1416
1314 } 1417 }
1315 } 1418 }
1419 lockPartsForRead(false);
1316 1420
1317 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1421 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1318 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1422 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1354,42 +1458,52 @@ namespace OpenSim.Region.Framework.Scenes
1354 /// <param name="m_physicalPrim"></param> 1458 /// <param name="m_physicalPrim"></param>
1355 public void ApplyPhysics(bool m_physicalPrim) 1459 public void ApplyPhysics(bool m_physicalPrim)
1356 { 1460 {
1357 lock (m_parts) 1461 lockPartsForRead(true);
1462
1463 if (m_parts.Count > 1)
1358 { 1464 {
1359 if (m_parts.Count > 1) 1465 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1466 lockPartsForRead(false);
1467 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1468 foreach (SceneObjectPart part in values)
1360 { 1469 {
1361 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1470
1362 foreach (SceneObjectPart part in m_parts.Values) 1471 if (part.LocalId != m_rootPart.LocalId)
1363 { 1472 {
1364 if (part.LocalId != m_rootPart.LocalId) 1473 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1365 {
1366 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1367 }
1368 } 1474 }
1369 1475
1370 // Hack to get the physics scene geometries in the right spot
1371 ResetChildPrimPhysicsPositions();
1372 }
1373 else
1374 {
1375 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1376 } 1476 }
1477 // Hack to get the physics scene geometries in the right spot
1478 ResetChildPrimPhysicsPositions();
1479 }
1480 else
1481 {
1482 lockPartsForRead(false);
1483 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1377 } 1484 }
1378 } 1485 }
1379 1486
1380 public void SetOwnerId(UUID userId) 1487 public void SetOwnerId(UUID userId)
1381 { 1488 {
1382 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1489 ForEachPart(delegate(SceneObjectPart part)
1490 {
1491
1492 part.OwnerID = userId;
1493
1494 });
1383 } 1495 }
1384 1496
1385 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1497 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1386 { 1498 {
1387 lock (m_parts) 1499 lockPartsForRead(true);
1500 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1501 lockPartsForRead(false);
1502 foreach (SceneObjectPart part in values)
1388 { 1503 {
1389 foreach (SceneObjectPart part in m_parts.Values) 1504
1390 { 1505 whatToDo(part);
1391 whatToDo(part); 1506
1392 }
1393 } 1507 }
1394 } 1508 }
1395 1509
@@ -1488,14 +1602,17 @@ namespace OpenSim.Region.Framework.Scenes
1488 { 1602 {
1489 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1603 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1490 1604
1491 lock (m_parts) 1605 lockPartsForRead(true);
1492 { 1606 {
1493 foreach (SceneObjectPart part in m_parts.Values) 1607 foreach (SceneObjectPart part in m_parts.Values)
1494 { 1608 {
1609
1495 if (part != RootPart) 1610 if (part != RootPart)
1496 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1611 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1612
1497 } 1613 }
1498 } 1614 }
1615 lockPartsForRead(false);
1499 } 1616 }
1500 1617
1501 /// <summary> 1618 /// <summary>
@@ -1593,10 +1710,11 @@ namespace OpenSim.Region.Framework.Scenes
1593 1710
1594 List<SceneObjectPart> partList; 1711 List<SceneObjectPart> partList;
1595 1712
1596 lock (m_parts) 1713 lockPartsForRead(true);
1597 { 1714
1598 partList = new List<SceneObjectPart>(m_parts.Values); 1715 partList = new List<SceneObjectPart>(m_parts.Values);
1599 } 1716
1717 lockPartsForRead(false);
1600 1718
1601 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1719 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1602 { 1720 {
@@ -1893,10 +2011,11 @@ namespace OpenSim.Region.Framework.Scenes
1893 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 2011 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1894 newPart.SetParent(this); 2012 newPart.SetParent(this);
1895 2013
1896 lock (m_parts) 2014 lockPartsForWrite(true);
1897 { 2015 {
1898 m_parts.Add(newPart.UUID, newPart); 2016 m_parts.Add(newPart.UUID, newPart);
1899 } 2017 }
2018 lockPartsForWrite(false);
1900 2019
1901 SetPartAsNonRoot(newPart); 2020 SetPartAsNonRoot(newPart);
1902 2021
@@ -1959,7 +2078,7 @@ namespace OpenSim.Region.Framework.Scenes
1959 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2078 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1960 // return; 2079 // return;
1961 2080
1962 lock (m_parts) 2081 lockPartsForRead(true);
1963 { 2082 {
1964 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2083 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1965 2084
@@ -1979,34 +2098,43 @@ namespace OpenSim.Region.Framework.Scenes
1979 { 2098 {
1980 if (!IsSelected) 2099 if (!IsSelected)
1981 part.UpdateLookAt(); 2100 part.UpdateLookAt();
2101
1982 part.SendScheduledUpdates(); 2102 part.SendScheduledUpdates();
2103
1983 } 2104 }
1984 } 2105 }
2106 lockPartsForRead(false);
1985 } 2107 }
1986 2108
1987 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2109 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1988 { 2110 {
1989 RootPart.AddFullUpdateToAvatar(presence); 2111 RootPart.AddFullUpdateToAvatar(presence);
1990 2112
1991 lock (m_parts) 2113 lockPartsForRead(true);
1992 { 2114 {
1993 foreach (SceneObjectPart part in m_parts.Values) 2115 foreach (SceneObjectPart part in m_parts.Values)
1994 { 2116 {
2117
1995 if (part != RootPart) 2118 if (part != RootPart)
1996 part.AddFullUpdateToAvatar(presence); 2119 part.AddFullUpdateToAvatar(presence);
2120
1997 } 2121 }
1998 } 2122 }
2123 lockPartsForRead(false);
1999 } 2124 }
2000 2125
2001 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2126 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
2002 { 2127 {
2003 lock (m_parts) 2128 lockPartsForRead(true);
2004 { 2129 {
2005 foreach (SceneObjectPart part in m_parts.Values) 2130 foreach (SceneObjectPart part in m_parts.Values)
2006 { 2131 {
2132
2007 part.AddTerseUpdateToAvatar(presence); 2133 part.AddTerseUpdateToAvatar(presence);
2134
2008 } 2135 }
2009 } 2136 }
2137 lockPartsForRead(false);
2010 } 2138 }
2011 2139
2012 /// <summary> 2140 /// <summary>
@@ -2017,14 +2145,17 @@ namespace OpenSim.Region.Framework.Scenes
2017 checkAtTargets(); 2145 checkAtTargets();
2018 RootPart.ScheduleFullUpdate(); 2146 RootPart.ScheduleFullUpdate();
2019 2147
2020 lock (m_parts) 2148 lockPartsForRead(true);
2021 { 2149 {
2022 foreach (SceneObjectPart part in m_parts.Values) 2150 foreach (SceneObjectPart part in m_parts.Values)
2023 { 2151 {
2152
2024 if (part != RootPart) 2153 if (part != RootPart)
2025 part.ScheduleFullUpdate(); 2154 part.ScheduleFullUpdate();
2155
2026 } 2156 }
2027 } 2157 }
2158 lockPartsForRead(false);
2028 } 2159 }
2029 2160
2030 /// <summary> 2161 /// <summary>
@@ -2032,13 +2163,16 @@ namespace OpenSim.Region.Framework.Scenes
2032 /// </summary> 2163 /// </summary>
2033 public void ScheduleGroupForTerseUpdate() 2164 public void ScheduleGroupForTerseUpdate()
2034 { 2165 {
2035 lock (m_parts) 2166 lockPartsForRead(true);
2036 { 2167 {
2037 foreach (SceneObjectPart part in m_parts.Values) 2168 foreach (SceneObjectPart part in m_parts.Values)
2038 { 2169 {
2170
2039 part.ScheduleTerseUpdate(); 2171 part.ScheduleTerseUpdate();
2172
2040 } 2173 }
2041 } 2174 }
2175 lockPartsForRead(false);
2042 } 2176 }
2043 2177
2044 /// <summary> 2178 /// <summary>
@@ -2051,14 +2185,17 @@ namespace OpenSim.Region.Framework.Scenes
2051 2185
2052 RootPart.SendFullUpdateToAllClients(); 2186 RootPart.SendFullUpdateToAllClients();
2053 2187
2054 lock (m_parts) 2188 lockPartsForRead(true);
2055 { 2189 {
2056 foreach (SceneObjectPart part in m_parts.Values) 2190 foreach (SceneObjectPart part in m_parts.Values)
2057 { 2191 {
2192
2058 if (part != RootPart) 2193 if (part != RootPart)
2059 part.SendFullUpdateToAllClients(); 2194 part.SendFullUpdateToAllClients();
2195
2060 } 2196 }
2061 } 2197 }
2198 lockPartsForRead(false);
2062 } 2199 }
2063 2200
2064 /// <summary> 2201 /// <summary>
@@ -2089,14 +2226,15 @@ namespace OpenSim.Region.Framework.Scenes
2089 { 2226 {
2090 if (IsDeleted) 2227 if (IsDeleted)
2091 return; 2228 return;
2092 2229
2093 lock (m_parts) 2230 lockPartsForRead(true);
2094 { 2231 {
2095 foreach (SceneObjectPart part in m_parts.Values) 2232 foreach (SceneObjectPart part in m_parts.Values)
2096 { 2233 {
2097 part.SendTerseUpdateToAllClients(); 2234 part.SendTerseUpdateToAllClients();
2098 } 2235 }
2099 } 2236 }
2237 lockPartsForRead(false);
2100 } 2238 }
2101 2239
2102 #endregion 2240 #endregion
@@ -2110,16 +2248,18 @@ namespace OpenSim.Region.Framework.Scenes
2110 /// <returns>null if no child part with that linknum or child part</returns> 2248 /// <returns>null if no child part with that linknum or child part</returns>
2111 public SceneObjectPart GetLinkNumPart(int linknum) 2249 public SceneObjectPart GetLinkNumPart(int linknum)
2112 { 2250 {
2113 lock (m_parts) 2251 lockPartsForRead(true);
2114 { 2252 {
2115 foreach (SceneObjectPart part in m_parts.Values) 2253 foreach (SceneObjectPart part in m_parts.Values)
2116 { 2254 {
2117 if (part.LinkNum == linknum) 2255 if (part.LinkNum == linknum)
2118 { 2256 {
2257 lockPartsForRead(false);
2119 return part; 2258 return part;
2120 } 2259 }
2121 } 2260 }
2122 } 2261 }
2262 lockPartsForRead(false);
2123 2263
2124 return null; 2264 return null;
2125 } 2265 }
@@ -2147,17 +2287,19 @@ namespace OpenSim.Region.Framework.Scenes
2147 public SceneObjectPart GetChildPart(uint localID) 2287 public SceneObjectPart GetChildPart(uint localID)
2148 { 2288 {
2149 //m_log.DebugFormat("Entered looking for {0}", localID); 2289 //m_log.DebugFormat("Entered looking for {0}", localID);
2150 lock (m_parts) 2290 lockPartsForRead(true);
2151 { 2291 {
2152 foreach (SceneObjectPart part in m_parts.Values) 2292 foreach (SceneObjectPart part in m_parts.Values)
2153 { 2293 {
2154 //m_log.DebugFormat("Found {0}", part.LocalId); 2294 //m_log.DebugFormat("Found {0}", part.LocalId);
2155 if (part.LocalId == localID) 2295 if (part.LocalId == localID)
2156 { 2296 {
2297 lockPartsForRead(false);
2157 return part; 2298 return part;
2158 } 2299 }
2159 } 2300 }
2160 } 2301 }
2302 lockPartsForRead(false);
2161 2303
2162 return null; 2304 return null;
2163 } 2305 }
@@ -2187,17 +2329,19 @@ namespace OpenSim.Region.Framework.Scenes
2187 public bool HasChildPrim(uint localID) 2329 public bool HasChildPrim(uint localID)
2188 { 2330 {
2189 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2331 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2190 lock (m_parts) 2332 lockPartsForRead(true);
2191 { 2333 {
2192 foreach (SceneObjectPart part in m_parts.Values) 2334 foreach (SceneObjectPart part in m_parts.Values)
2193 { 2335 {
2194 //m_log.DebugFormat("Found {0}", part.LocalId); 2336 //m_log.DebugFormat("Found {0}", part.LocalId);
2195 if (part.LocalId == localID) 2337 if (part.LocalId == localID)
2196 { 2338 {
2339 lockPartsForRead(false);
2197 return true; 2340 return true;
2198 } 2341 }
2199 } 2342 }
2200 } 2343 }
2344 lockPartsForRead(false);
2201 2345
2202 return false; 2346 return false;
2203 } 2347 }
@@ -2247,53 +2391,57 @@ namespace OpenSim.Region.Framework.Scenes
2247 if (m_rootPart.LinkNum == 0) 2391 if (m_rootPart.LinkNum == 0)
2248 m_rootPart.LinkNum = 1; 2392 m_rootPart.LinkNum = 1;
2249 2393
2250 lock (m_parts) 2394 lockPartsForWrite(true);
2251 { 2395
2252 m_parts.Add(linkPart.UUID, linkPart); 2396 m_parts.Add(linkPart.UUID, linkPart);
2397
2398 lockPartsForWrite(false);
2253 2399
2254 // Insert in terms of link numbers, the new links 2400 // Insert in terms of link numbers, the new links
2255 // before the current ones (with the exception of 2401 // before the current ones (with the exception of
2256 // the root prim. Shuffle the old ones up 2402 // the root prim. Shuffle the old ones up
2257 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2403 lockPartsForRead(true);
2404 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2405 {
2406 if (kvp.Value.LinkNum != 1)
2258 { 2407 {
2259 if (kvp.Value.LinkNum != 1) 2408 // Don't update root prim link number
2260 { 2409 kvp.Value.LinkNum += objectGroup.PrimCount;
2261 // Don't update root prim link number
2262 kvp.Value.LinkNum += objectGroup.PrimCount;
2263 }
2264 } 2410 }
2411 }
2412 lockPartsForRead(false);
2265 2413
2266 linkPart.LinkNum = 2; 2414 linkPart.LinkNum = 2;
2267 2415
2268 linkPart.SetParent(this); 2416 linkPart.SetParent(this);
2269 linkPart.AddFlag(PrimFlags.CreateSelected); 2417 linkPart.AddFlag(PrimFlags.CreateSelected);
2270 2418
2271 //if (linkPart.PhysActor != null) 2419 //if (linkPart.PhysActor != null)
2272 //{ 2420 //{
2273 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2421 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2274 2422
2275 //linkPart.PhysActor = null; 2423 //linkPart.PhysActor = null;
2276 //} 2424 //}
2277 2425
2278 //TODO: rest of parts 2426 //TODO: rest of parts
2279 int linkNum = 3; 2427 int linkNum = 3;
2280 foreach (SceneObjectPart part in objectGroup.Children.Values) 2428 foreach (SceneObjectPart part in objectGroup.Children.Values)
2429 {
2430 if (part.UUID != objectGroup.m_rootPart.UUID)
2281 { 2431 {
2282 if (part.UUID != objectGroup.m_rootPart.UUID) 2432 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2283 {
2284 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2285 }
2286 part.ClearUndoState();
2287 } 2433 }
2434 part.ClearUndoState();
2288 } 2435 }
2289 2436
2290 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2437 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2291 objectGroup.m_isDeleted = true; 2438 objectGroup.m_isDeleted = true;
2439
2440 objectGroup.lockPartsForWrite(true);
2292 2441
2293 lock (objectGroup.m_parts) 2442 objectGroup.m_parts.Clear();
2294 { 2443
2295 objectGroup.m_parts.Clear(); 2444 objectGroup.lockPartsForWrite(false);
2296 }
2297 2445
2298 // Can't do this yet since backup still makes use of the root part without any synchronization 2446 // Can't do this yet since backup still makes use of the root part without any synchronization
2299// objectGroup.m_rootPart = null; 2447// objectGroup.m_rootPart = null;
@@ -2363,11 +2511,12 @@ namespace OpenSim.Region.Framework.Scenes
2363 Quaternion worldRot = linkPart.GetWorldRotation(); 2511 Quaternion worldRot = linkPart.GetWorldRotation();
2364 2512
2365 // Remove the part from this object 2513 // Remove the part from this object
2366 lock (m_parts) 2514 lockPartsForWrite(true);
2367 { 2515 {
2368 m_parts.Remove(linkPart.UUID); 2516 m_parts.Remove(linkPart.UUID);
2369 } 2517 }
2370 2518 lockPartsForWrite(false);
2519 lockPartsForRead(true);
2371 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2520 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2372 RootPart.LinkNum = 0; 2521 RootPart.LinkNum = 0;
2373 else 2522 else
@@ -2378,6 +2527,7 @@ namespace OpenSim.Region.Framework.Scenes
2378 p.LinkNum--; 2527 p.LinkNum--;
2379 } 2528 }
2380 } 2529 }
2530 lockPartsForRead(false);
2381 2531
2382 linkPart.ParentID = 0; 2532 linkPart.ParentID = 0;
2383 linkPart.LinkNum = 0; 2533 linkPart.LinkNum = 0;
@@ -2699,9 +2849,12 @@ namespace OpenSim.Region.Framework.Scenes
2699 2849
2700 if (selectionPart != null) 2850 if (selectionPart != null)
2701 { 2851 {
2702 lock (m_parts) 2852 lockPartsForRead(true);
2853 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2854 lockPartsForRead(false);
2855 foreach (SceneObjectPart part in parts)
2703 { 2856 {
2704 foreach (SceneObjectPart part in m_parts.Values) 2857 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2705 { 2858 {
2706 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2859 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2707 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2860 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2711,12 +2864,13 @@ namespace OpenSim.Region.Framework.Scenes
2711 break; 2864 break;
2712 } 2865 }
2713 } 2866 }
2867 }
2714 2868
2715 foreach (SceneObjectPart part in m_parts.Values) 2869 foreach (SceneObjectPart part in parts)
2716 { 2870 {
2717 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2871 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2718 }
2719 } 2872 }
2873
2720 } 2874 }
2721 } 2875 }
2722 2876
@@ -2802,11 +2956,9 @@ namespace OpenSim.Region.Framework.Scenes
2802 scale.Y = m_scene.m_maxNonphys; 2956 scale.Y = m_scene.m_maxNonphys;
2803 if (scale.Z > m_scene.m_maxNonphys) 2957 if (scale.Z > m_scene.m_maxNonphys)
2804 scale.Z = m_scene.m_maxNonphys; 2958 scale.Z = m_scene.m_maxNonphys;
2805
2806 SceneObjectPart part = GetChildPart(localID); 2959 SceneObjectPart part = GetChildPart(localID);
2807 if (part != null) 2960 if (part != null)
2808 { 2961 {
2809 part.Resize(scale);
2810 if (part.PhysActor != null) 2962 if (part.PhysActor != null)
2811 { 2963 {
2812 if (part.PhysActor.IsPhysical) 2964 if (part.PhysActor.IsPhysical)
@@ -2821,7 +2973,7 @@ namespace OpenSim.Region.Framework.Scenes
2821 part.PhysActor.Size = scale; 2973 part.PhysActor.Size = scale;
2822 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2974 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2823 } 2975 }
2824 //if (part.UUID != m_rootPart.UUID) 2976 part.Resize(scale);
2825 2977
2826 HasGroupChanged = true; 2978 HasGroupChanged = true;
2827 ScheduleGroupForFullUpdate(); 2979 ScheduleGroupForFullUpdate();
@@ -2863,73 +3015,71 @@ namespace OpenSim.Region.Framework.Scenes
2863 float y = (scale.Y / part.Scale.Y); 3015 float y = (scale.Y / part.Scale.Y);
2864 float z = (scale.Z / part.Scale.Z); 3016 float z = (scale.Z / part.Scale.Z);
2865 3017
2866 lock (m_parts) 3018 lockPartsForRead(true);
3019 if (x > 1.0f || y > 1.0f || z > 1.0f)
2867 { 3020 {
2868 if (x > 1.0f || y > 1.0f || z > 1.0f) 3021 foreach (SceneObjectPart obPart in m_parts.Values)
2869 { 3022 {
2870 foreach (SceneObjectPart obPart in m_parts.Values) 3023 if (obPart.UUID != m_rootPart.UUID)
2871 { 3024 {
2872 if (obPart.UUID != m_rootPart.UUID) 3025 Vector3 oldSize = new Vector3(obPart.Scale);
2873 { 3026 obPart.IgnoreUndoUpdate = true;
2874 obPart.IgnoreUndoUpdate = true;
2875 Vector3 oldSize = new Vector3(obPart.Scale);
2876 3027
2877 float f = 1.0f; 3028 float f = 1.0f;
2878 float a = 1.0f; 3029 float a = 1.0f;
2879 3030
2880 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3031 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3032 {
3033 if (oldSize.X*x > m_scene.m_maxPhys)
2881 { 3034 {
2882 if (oldSize.X*x > m_scene.m_maxPhys) 3035 f = m_scene.m_maxPhys / oldSize.X;
2883 { 3036 a = f / x;
2884 f = m_scene.m_maxPhys / oldSize.X; 3037 x *= a;
2885 a = f / x; 3038 y *= a;
2886 x *= a; 3039 z *= a;
2887 y *= a;
2888 z *= a;
2889 }
2890 if (oldSize.Y*y > m_scene.m_maxPhys)
2891 {
2892 f = m_scene.m_maxPhys / oldSize.Y;
2893 a = f / y;
2894 x *= a;
2895 y *= a;
2896 z *= a;
2897 }
2898 if (oldSize.Z*z > m_scene.m_maxPhys)
2899 {
2900 f = m_scene.m_maxPhys / oldSize.Z;
2901 a = f / z;
2902 x *= a;
2903 y *= a;
2904 z *= a;
2905 }
2906 } 3040 }
2907 else 3041 if (oldSize.Y*y > m_scene.m_maxPhys)
3042 {
3043 f = m_scene.m_maxPhys / oldSize.Y;
3044 a = f / y;
3045 x *= a;
3046 y *= a;
3047 z *= a;
3048 }
3049 if (oldSize.Z*z > m_scene.m_maxPhys)
3050 {
3051 f = m_scene.m_maxPhys / oldSize.Z;
3052 a = f / z;
3053 x *= a;
3054 y *= a;
3055 z *= a;
3056 }
3057 }
3058 else
3059 {
3060 if (oldSize.X*x > m_scene.m_maxNonphys)
3061 {
3062 f = m_scene.m_maxNonphys / oldSize.X;
3063 a = f / x;
3064 x *= a;
3065 y *= a;
3066 z *= a;
3067 }
3068 if (oldSize.Y*y > m_scene.m_maxNonphys)
3069 {
3070 f = m_scene.m_maxNonphys / oldSize.Y;
3071 a = f / y;
3072 x *= a;
3073 y *= a;
3074 z *= a;
3075 }
3076 if (oldSize.Z*z > m_scene.m_maxNonphys)
2908 { 3077 {
2909 if (oldSize.X*x > m_scene.m_maxNonphys) 3078 f = m_scene.m_maxNonphys / oldSize.Z;
2910 { 3079 a = f / z;
2911 f = m_scene.m_maxNonphys / oldSize.X; 3080 x *= a;
2912 a = f / x; 3081 y *= a;
2913 x *= a; 3082 z *= a;
2914 y *= a;
2915 z *= a;
2916 }
2917 if (oldSize.Y*y > m_scene.m_maxNonphys)
2918 {
2919 f = m_scene.m_maxNonphys / oldSize.Y;
2920 a = f / y;
2921 x *= a;
2922 y *= a;
2923 z *= a;
2924 }
2925 if (oldSize.Z*z > m_scene.m_maxNonphys)
2926 {
2927 f = m_scene.m_maxNonphys / oldSize.Z;
2928 a = f / z;
2929 x *= a;
2930 y *= a;
2931 z *= a;
2932 }
2933 } 3083 }
2934 obPart.IgnoreUndoUpdate = false; 3084 obPart.IgnoreUndoUpdate = false;
2935 obPart.StoreUndoState(); 3085 obPart.StoreUndoState();
@@ -2937,6 +3087,7 @@ namespace OpenSim.Region.Framework.Scenes
2937 } 3087 }
2938 } 3088 }
2939 } 3089 }
3090 lockPartsForRead(false);
2940 3091
2941 Vector3 prevScale = part.Scale; 3092 Vector3 prevScale = part.Scale;
2942 prevScale.X *= x; 3093 prevScale.X *= x;
@@ -2944,7 +3095,7 @@ namespace OpenSim.Region.Framework.Scenes
2944 prevScale.Z *= z; 3095 prevScale.Z *= z;
2945 part.Resize(prevScale); 3096 part.Resize(prevScale);
2946 3097
2947 lock (m_parts) 3098 lockPartsForRead(true);
2948 { 3099 {
2949 foreach (SceneObjectPart obPart in m_parts.Values) 3100 foreach (SceneObjectPart obPart in m_parts.Values)
2950 { 3101 {
@@ -2966,6 +3117,7 @@ namespace OpenSim.Region.Framework.Scenes
2966 obPart.StoreUndoState(); 3117 obPart.StoreUndoState();
2967 } 3118 }
2968 } 3119 }
3120 lockPartsForRead(false);
2969 3121
2970 if (part.PhysActor != null) 3122 if (part.PhysActor != null)
2971 { 3123 {
@@ -3068,7 +3220,7 @@ namespace OpenSim.Region.Framework.Scenes
3068 axDiff *= Quaternion.Inverse(partRotation); 3220 axDiff *= Quaternion.Inverse(partRotation);
3069 diff = axDiff; 3221 diff = axDiff;
3070 3222
3071 lock (m_parts) 3223 lockPartsForRead(true);
3072 { 3224 {
3073 foreach (SceneObjectPart obPart in m_parts.Values) 3225 foreach (SceneObjectPart obPart in m_parts.Values)
3074 { 3226 {
@@ -3078,6 +3230,7 @@ namespace OpenSim.Region.Framework.Scenes
3078 } 3230 }
3079 } 3231 }
3080 } 3232 }
3233 lockPartsForRead(false);
3081 3234
3082 AbsolutePosition = newPos; 3235 AbsolutePosition = newPos;
3083 3236
@@ -3211,7 +3364,7 @@ namespace OpenSim.Region.Framework.Scenes
3211 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3364 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3212 } 3365 }
3213 3366
3214 lock (m_parts) 3367 lockPartsForRead(true);
3215 { 3368 {
3216 foreach (SceneObjectPart prim in m_parts.Values) 3369 foreach (SceneObjectPart prim in m_parts.Values)
3217 { 3370 {
@@ -3230,6 +3383,7 @@ namespace OpenSim.Region.Framework.Scenes
3230 } 3383 }
3231 } 3384 }
3232 } 3385 }
3386
3233 foreach (SceneObjectPart childpart in Children.Values) 3387 foreach (SceneObjectPart childpart in Children.Values)
3234 { 3388 {
3235 if (childpart != m_rootPart) 3389 if (childpart != m_rootPart)
@@ -3238,6 +3392,9 @@ namespace OpenSim.Region.Framework.Scenes
3238 childpart.StoreUndoState(); 3392 childpart.StoreUndoState();
3239 } 3393 }
3240 } 3394 }
3395
3396 lockPartsForRead(false);
3397
3241 m_rootPart.ScheduleTerseUpdate(); 3398 m_rootPart.ScheduleTerseUpdate();
3242 } 3399 }
3243 3400
@@ -3359,7 +3516,7 @@ namespace OpenSim.Region.Framework.Scenes
3359 if (atTargets.Count > 0) 3516 if (atTargets.Count > 0)
3360 { 3517 {
3361 uint[] localids = new uint[0]; 3518 uint[] localids = new uint[0];
3362 lock (m_parts) 3519 lockPartsForRead(true);
3363 { 3520 {
3364 localids = new uint[m_parts.Count]; 3521 localids = new uint[m_parts.Count];
3365 int cntr = 0; 3522 int cntr = 0;
@@ -3369,6 +3526,7 @@ namespace OpenSim.Region.Framework.Scenes
3369 cntr++; 3526 cntr++;
3370 } 3527 }
3371 } 3528 }
3529 lockPartsForRead(false);
3372 3530
3373 for (int ctr = 0; ctr < localids.Length; ctr++) 3531 for (int ctr = 0; ctr < localids.Length; ctr++)
3374 { 3532 {
@@ -3387,7 +3545,7 @@ namespace OpenSim.Region.Framework.Scenes
3387 { 3545 {
3388 //trigger not_at_target 3546 //trigger not_at_target
3389 uint[] localids = new uint[0]; 3547 uint[] localids = new uint[0];
3390 lock (m_parts) 3548 lockPartsForRead(true);
3391 { 3549 {
3392 localids = new uint[m_parts.Count]; 3550 localids = new uint[m_parts.Count];
3393 int cntr = 0; 3551 int cntr = 0;
@@ -3397,7 +3555,8 @@ namespace OpenSim.Region.Framework.Scenes
3397 cntr++; 3555 cntr++;
3398 } 3556 }
3399 } 3557 }
3400 3558 lockPartsForRead(false);
3559
3401 for (int ctr = 0; ctr < localids.Length; ctr++) 3560 for (int ctr = 0; ctr < localids.Length; ctr++)
3402 { 3561 {
3403 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3562 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3489,19 +3648,20 @@ namespace OpenSim.Region.Framework.Scenes
3489 public float GetMass() 3648 public float GetMass()
3490 { 3649 {
3491 float retmass = 0f; 3650 float retmass = 0f;
3492 lock (m_parts) 3651 lockPartsForRead(true);
3493 { 3652 {
3494 foreach (SceneObjectPart part in m_parts.Values) 3653 foreach (SceneObjectPart part in m_parts.Values)
3495 { 3654 {
3496 retmass += part.GetMass(); 3655 retmass += part.GetMass();
3497 } 3656 }
3498 } 3657 }
3658 lockPartsForRead(false);
3499 return retmass; 3659 return retmass;
3500 } 3660 }
3501 3661
3502 public void CheckSculptAndLoad() 3662 public void CheckSculptAndLoad()
3503 { 3663 {
3504 lock (m_parts) 3664 lockPartsForRead(true);
3505 { 3665 {
3506 if (!IsDeleted) 3666 if (!IsDeleted)
3507 { 3667 {
@@ -3526,6 +3686,7 @@ namespace OpenSim.Region.Framework.Scenes
3526 } 3686 }
3527 } 3687 }
3528 } 3688 }
3689 lockPartsForRead(false);
3529 } 3690 }
3530 3691
3531 protected void AssetReceived(string id, Object sender, AssetBase asset) 3692 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3546,7 +3707,7 @@ namespace OpenSim.Region.Framework.Scenes
3546 /// <param name="client"></param> 3707 /// <param name="client"></param>
3547 public void SetGroup(UUID GroupID, IClientAPI client) 3708 public void SetGroup(UUID GroupID, IClientAPI client)
3548 { 3709 {
3549 lock (m_parts) 3710 lockPartsForRead(true);
3550 { 3711 {
3551 foreach (SceneObjectPart part in m_parts.Values) 3712 foreach (SceneObjectPart part in m_parts.Values)
3552 { 3713 {
@@ -3556,7 +3717,7 @@ namespace OpenSim.Region.Framework.Scenes
3556 3717
3557 HasGroupChanged = true; 3718 HasGroupChanged = true;
3558 } 3719 }
3559 3720 lockPartsForRead(false);
3560 ScheduleGroupForFullUpdate(); 3721 ScheduleGroupForFullUpdate();
3561 } 3722 }
3562 3723
@@ -3575,11 +3736,12 @@ namespace OpenSim.Region.Framework.Scenes
3575 3736
3576 public void SetAttachmentPoint(byte point) 3737 public void SetAttachmentPoint(byte point)
3577 { 3738 {
3578 lock (m_parts) 3739 lockPartsForRead(true);
3579 { 3740 {
3580 foreach (SceneObjectPart part in m_parts.Values) 3741 foreach (SceneObjectPart part in m_parts.Values)
3581 part.SetAttachmentPoint(point); 3742 part.SetAttachmentPoint(point);
3582 } 3743 }
3744 lockPartsForRead(false);
3583 } 3745 }
3584 3746
3585 #region ISceneObject 3747 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 5c283bc..57635f5 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -147,7 +147,7 @@ namespace OpenSim.Region.Framework.Scenes
147 147
148 // TODO: This needs to be persisted in next XML version update! 148 // TODO: This needs to be persisted in next XML version update!
149 [XmlIgnore] 149 [XmlIgnore]
150 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 150 public int[] PayPrice = {-2,-2,-2,-2,-2};
151 [XmlIgnore] 151 [XmlIgnore]
152 public PhysicsActor PhysActor; 152 public PhysicsActor PhysActor;
153 153
@@ -274,6 +274,7 @@ namespace OpenSim.Region.Framework.Scenes
274 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 274 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
275 private Vector3 m_sitTargetPosition; 275 private Vector3 m_sitTargetPosition;
276 private string m_sitAnimation = "SIT"; 276 private string m_sitAnimation = "SIT";
277 private bool m_occupied; // KF if any av is sitting on this prim
277 private string m_text = String.Empty; 278 private string m_text = String.Empty;
278 private string m_touchName = String.Empty; 279 private string m_touchName = String.Empty;
279 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 280 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -452,12 +453,16 @@ namespace OpenSim.Region.Framework.Scenes
452 } 453 }
453 454
454 /// <value> 455 /// <value>
455 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 456 /// Get the inventory list
456 /// </value> 457 /// </value>
457 public TaskInventoryDictionary TaskInventory 458 public TaskInventoryDictionary TaskInventory
458 { 459 {
459 get { return m_inventory.Items; } 460 get {
460 set { m_inventory.Items = value; } 461 return m_inventory.Items;
462 }
463 set {
464 m_inventory.Items = value;
465 }
461 } 466 }
462 467
463 public uint ObjectFlags 468 public uint ObjectFlags
@@ -586,14 +591,12 @@ namespace OpenSim.Region.Framework.Scenes
586 set { m_LoopSoundSlavePrims = value; } 591 set { m_LoopSoundSlavePrims = value; }
587 } 592 }
588 593
589 [XmlIgnore]
590 public Byte[] TextureAnimation 594 public Byte[] TextureAnimation
591 { 595 {
592 get { return m_TextureAnimation; } 596 get { return m_TextureAnimation; }
593 set { m_TextureAnimation = value; } 597 set { m_TextureAnimation = value; }
594 } 598 }
595 599
596 [XmlIgnore]
597 public Byte[] ParticleSystem 600 public Byte[] ParticleSystem
598 { 601 {
599 get { return m_particleSystem; } 602 get { return m_particleSystem; }
@@ -647,7 +650,6 @@ namespace OpenSim.Region.Framework.Scenes
647 set 650 set
648 { 651 {
649 m_groupPosition = value; 652 m_groupPosition = value;
650
651 PhysicsActor actor = PhysActor; 653 PhysicsActor actor = PhysActor;
652 if (actor != null) 654 if (actor != null)
653 { 655 {
@@ -960,7 +962,8 @@ namespace OpenSim.Region.Framework.Scenes
960 if (IsAttachment) 962 if (IsAttachment)
961 return GroupPosition; 963 return GroupPosition;
962 964
963 return m_offsetPosition + m_groupPosition; } 965// return m_offsetPosition + m_groupPosition; }
966 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
964 } 967 }
965 968
966 public SceneObjectGroup ParentGroup 969 public SceneObjectGroup ParentGroup
@@ -1112,6 +1115,13 @@ namespace OpenSim.Region.Framework.Scenes
1112 get { return _flags; } 1115 get { return _flags; }
1113 set { _flags = value; } 1116 set { _flags = value; }
1114 } 1117 }
1118
1119 [XmlIgnore]
1120 public bool IsOccupied // KF If an av is sittingon this prim
1121 {
1122 get { return m_occupied; }
1123 set { m_occupied = value; }
1124 }
1115 1125
1116 [XmlIgnore] 1126 [XmlIgnore]
1117 public UUID SitTargetAvatar 1127 public UUID SitTargetAvatar
@@ -1187,14 +1197,6 @@ namespace OpenSim.Region.Framework.Scenes
1187 } 1197 }
1188 } 1198 }
1189 1199
1190 /// <summary>
1191 /// Clear all pending updates of parts to clients
1192 /// </summary>
1193 private void ClearUpdateSchedule()
1194 {
1195 m_updateFlag = 0;
1196 }
1197
1198 private void SendObjectPropertiesToClient(UUID AgentID) 1200 private void SendObjectPropertiesToClient(UUID AgentID)
1199 { 1201 {
1200 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1202 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1937,12 +1939,17 @@ namespace OpenSim.Region.Framework.Scenes
1937 public Vector3 GetWorldPosition() 1939 public Vector3 GetWorldPosition()
1938 { 1940 {
1939 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1941 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1940
1941 Vector3 axPos = OffsetPosition; 1942 Vector3 axPos = OffsetPosition;
1942
1943 axPos *= parentRot; 1943 axPos *= parentRot;
1944 Vector3 translationOffsetPosition = axPos; 1944 Vector3 translationOffsetPosition = axPos;
1945 return GroupPosition + translationOffsetPosition; 1945 if(_parentID == 0)
1946 {
1947 return GroupPosition;
1948 }
1949 else
1950 {
1951 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1952 }
1946 } 1953 }
1947 1954
1948 /// <summary> 1955 /// <summary>
@@ -1953,7 +1960,7 @@ namespace OpenSim.Region.Framework.Scenes
1953 { 1960 {
1954 Quaternion newRot; 1961 Quaternion newRot;
1955 1962
1956 if (this.LinkNum == 0) 1963 if (this.LinkNum < 2) //KF Single or root prim
1957 { 1964 {
1958 newRot = RotationOffset; 1965 newRot = RotationOffset;
1959 } 1966 }
@@ -2610,17 +2617,18 @@ namespace OpenSim.Region.Framework.Scenes
2610 //Trys to fetch sound id from prim's inventory. 2617 //Trys to fetch sound id from prim's inventory.
2611 //Prim's inventory doesn't support non script items yet 2618 //Prim's inventory doesn't support non script items yet
2612 2619
2613 lock (TaskInventory) 2620 TaskInventory.LockItemsForRead(true);
2621
2622 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2614 { 2623 {
2615 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2624 if (item.Value.Name == sound)
2616 { 2625 {
2617 if (item.Value.Name == sound) 2626 soundID = item.Value.ItemID;
2618 { 2627 break;
2619 soundID = item.Value.ItemID;
2620 break;
2621 }
2622 } 2628 }
2623 } 2629 }
2630
2631 TaskInventory.LockItemsForRead(false);
2624 } 2632 }
2625 2633
2626 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2634 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2927,8 +2935,8 @@ namespace OpenSim.Region.Framework.Scenes
2927 { 2935 {
2928 const float ROTATION_TOLERANCE = 0.01f; 2936 const float ROTATION_TOLERANCE = 0.01f;
2929 const float VELOCITY_TOLERANCE = 0.001f; 2937 const float VELOCITY_TOLERANCE = 0.001f;
2930 const float POSITION_TOLERANCE = 0.05f; 2938 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2931 const int TIME_MS_TOLERANCE = 3000; 2939 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2932 2940
2933 if (m_updateFlag == 1) 2941 if (m_updateFlag == 1)
2934 { 2942 {
@@ -2942,7 +2950,7 @@ namespace OpenSim.Region.Framework.Scenes
2942 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2950 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2943 { 2951 {
2944 AddTerseUpdateToAllAvatars(); 2952 AddTerseUpdateToAllAvatars();
2945 ClearUpdateSchedule(); 2953
2946 2954
2947 // This causes the Scene to 'poll' physical objects every couple of frames 2955 // This causes the Scene to 'poll' physical objects every couple of frames
2948 // bad, so it's been replaced by an event driven method. 2956 // bad, so it's been replaced by an event driven method.
@@ -2960,16 +2968,18 @@ namespace OpenSim.Region.Framework.Scenes
2960 m_lastAngularVelocity = AngularVelocity; 2968 m_lastAngularVelocity = AngularVelocity;
2961 m_lastTerseSent = Environment.TickCount; 2969 m_lastTerseSent = Environment.TickCount;
2962 } 2970 }
2971 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2972 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2963 } 2973 }
2964 else 2974 else
2965 { 2975 {
2966 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2976 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2967 { 2977 {
2968 AddFullUpdateToAllAvatars(); 2978 AddFullUpdateToAllAvatars();
2969 ClearUpdateSchedule(); 2979 m_updateFlag = 0; //Same here
2970 } 2980 }
2971 } 2981 }
2972 ClearUpdateSchedule(); 2982 m_updateFlag = 0;
2973 } 2983 }
2974 2984
2975 /// <summary> 2985 /// <summary>
@@ -2996,17 +3006,16 @@ namespace OpenSim.Region.Framework.Scenes
2996 if (!UUID.TryParse(sound, out soundID)) 3006 if (!UUID.TryParse(sound, out soundID))
2997 { 3007 {
2998 // search sound file from inventory 3008 // search sound file from inventory
2999 lock (TaskInventory) 3009 TaskInventory.LockItemsForRead(true);
3010 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3000 { 3011 {
3001 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3012 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3002 { 3013 {
3003 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3014 soundID = item.Value.ItemID;
3004 { 3015 break;
3005 soundID = item.Value.ItemID;
3006 break;
3007 }
3008 } 3016 }
3009 } 3017 }
3018 TaskInventory.LockItemsForRead(false);
3010 } 3019 }
3011 3020
3012 if (soundID == UUID.Zero) 3021 if (soundID == UUID.Zero)
@@ -3189,6 +3198,22 @@ namespace OpenSim.Region.Framework.Scenes
3189 PhysActor.VehicleRotationParam(param, rotation); 3198 PhysActor.VehicleRotationParam(param, rotation);
3190 } 3199 }
3191 } 3200 }
3201
3202 public void SetVehicleFlags(int flags)
3203 {
3204 if (PhysActor != null)
3205 {
3206 PhysActor.VehicleFlagsSet(flags);
3207 }
3208 }
3209
3210 public void RemoveVehicleFlags(int flags)
3211 {
3212 if (PhysActor != null)
3213 {
3214 PhysActor.VehicleFlagsRemove(flags);
3215 }
3216 }
3192 3217
3193 /// <summary> 3218 /// <summary>
3194 /// Set the color of prim faces 3219 /// Set the color of prim faces
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 04e3221..013285f 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -81,7 +81,9 @@ namespace OpenSim.Region.Framework.Scenes
81 /// </value> 81 /// </value>
82 protected internal TaskInventoryDictionary Items 82 protected internal TaskInventoryDictionary Items
83 { 83 {
84 get { return m_items; } 84 get {
85 return m_items;
86 }
85 set 87 set
86 { 88 {
87 m_items = value; 89 m_items = value;
@@ -117,22 +119,25 @@ namespace OpenSim.Region.Framework.Scenes
117 /// <param name="linkNum">Link number for the part</param> 119 /// <param name="linkNum">Link number for the part</param>
118 public void ResetInventoryIDs() 120 public void ResetInventoryIDs()
119 { 121 {
120 lock (Items) 122 m_items.LockItemsForWrite(true);
123
124 if (0 == Items.Count)
121 { 125 {
122 if (0 == Items.Count) 126 m_items.LockItemsForWrite(false);
123 return; 127 return;
128 }
124 129
125 HasInventoryChanged = true; 130 HasInventoryChanged = true;
126 m_part.ParentGroup.HasGroupChanged = true; 131 m_part.ParentGroup.HasGroupChanged = true;
127 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 132 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
128 Items.Clear(); 133 Items.Clear();
129 134
130 foreach (TaskInventoryItem item in items) 135 foreach (TaskInventoryItem item in items)
131 { 136 {
132 item.ResetIDs(m_part.UUID); 137 item.ResetIDs(m_part.UUID);
133 Items.Add(item.ItemID, item); 138 Items.Add(item.ItemID, item);
134 }
135 } 139 }
140 m_items.LockItemsForWrite(false);
136 } 141 }
137 142
138 /// <summary> 143 /// <summary>
@@ -141,25 +146,25 @@ namespace OpenSim.Region.Framework.Scenes
141 /// <param name="ownerId"></param> 146 /// <param name="ownerId"></param>
142 public void ChangeInventoryOwner(UUID ownerId) 147 public void ChangeInventoryOwner(UUID ownerId)
143 { 148 {
144 lock (Items) 149 m_items.LockItemsForWrite(true);
150 if (0 == Items.Count)
145 { 151 {
146 if (0 == Items.Count) 152 m_items.LockItemsForWrite(false);
147 { 153 return;
148 return; 154 }
149 }
150 155
151 HasInventoryChanged = true; 156 HasInventoryChanged = true;
152 m_part.ParentGroup.HasGroupChanged = true; 157 m_part.ParentGroup.HasGroupChanged = true;
153 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
154 foreach (TaskInventoryItem item in items) 159 foreach (TaskInventoryItem item in items)
160 {
161 if (ownerId != item.OwnerID)
155 { 162 {
156 if (ownerId != item.OwnerID) 163 item.LastOwnerID = item.OwnerID;
157 { 164 item.OwnerID = ownerId;
158 item.LastOwnerID = item.OwnerID;
159 item.OwnerID = ownerId;
160 }
161 } 165 }
162 } 166 }
167 m_items.LockItemsForWrite(false);
163 } 168 }
164 169
165 /// <summary> 170 /// <summary>
@@ -168,24 +173,24 @@ namespace OpenSim.Region.Framework.Scenes
168 /// <param name="groupID"></param> 173 /// <param name="groupID"></param>
169 public void ChangeInventoryGroup(UUID groupID) 174 public void ChangeInventoryGroup(UUID groupID)
170 { 175 {
171 lock (Items) 176 m_items.LockItemsForWrite(true);
177 if (0 == Items.Count)
172 { 178 {
173 if (0 == Items.Count) 179 m_items.LockItemsForWrite(false);
174 { 180 return;
175 return; 181 }
176 }
177 182
178 HasInventoryChanged = true; 183 HasInventoryChanged = true;
179 m_part.ParentGroup.HasGroupChanged = true; 184 m_part.ParentGroup.HasGroupChanged = true;
180 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 185 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
181 foreach (TaskInventoryItem item in items) 186 foreach (TaskInventoryItem item in items)
187 {
188 if (groupID != item.GroupID)
182 { 189 {
183 if (groupID != item.GroupID) 190 item.GroupID = groupID;
184 {
185 item.GroupID = groupID;
186 }
187 } 191 }
188 } 192 }
193 m_items.LockItemsForWrite(false);
189 } 194 }
190 195
191 /// <summary> 196 /// <summary>
@@ -193,14 +198,14 @@ namespace OpenSim.Region.Framework.Scenes
193 /// </summary> 198 /// </summary>
194 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 199 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
195 { 200 {
196 lock (m_items) 201 Items.LockItemsForRead(true);
202 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
203 Items.LockItemsForRead(false);
204 foreach (TaskInventoryItem item in items)
197 { 205 {
198 foreach (TaskInventoryItem item in Items.Values) 206 if ((int)InventoryType.LSL == item.InvType)
199 { 207 {
200 if ((int)InventoryType.LSL == item.InvType) 208 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
201 {
202 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
203 }
204 } 209 }
205 } 210 }
206 } 211 }
@@ -235,16 +240,20 @@ namespace OpenSim.Region.Framework.Scenes
235 /// </param> 240 /// </param>
236 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 241 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
237 { 242 {
238 lock (Items) 243 Items.LockItemsForRead(true);
244 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
245 Items.LockItemsForRead(false);
246
247 foreach (TaskInventoryItem item in items)
239 { 248 {
240 foreach (TaskInventoryItem item in Items.Values) 249 if ((int)InventoryType.LSL == item.InvType)
241 { 250 {
242 if ((int)InventoryType.LSL == item.InvType) 251 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
243 { 252 m_part.RemoveScriptEvents(item.ItemID);
244 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
245 }
246 } 253 }
247 } 254 }
255
256
248 } 257 }
249 258
250 /// <summary> 259 /// <summary>
@@ -269,12 +278,10 @@ namespace OpenSim.Region.Framework.Scenes
269 if (stateSource == 1 && // Prim crossing 278 if (stateSource == 1 && // Prim crossing
270 m_part.ParentGroup.Scene.m_trustBinaries) 279 m_part.ParentGroup.Scene.m_trustBinaries)
271 { 280 {
272 lock (m_items) 281 m_items.LockItemsForWrite(true);
273 { 282 m_items[item.ItemID].PermsMask = 0;
274 m_items[item.ItemID].PermsMask = 0; 283 m_items[item.ItemID].PermsGranter = UUID.Zero;
275 m_items[item.ItemID].PermsGranter = UUID.Zero; 284 m_items.LockItemsForWrite(false);
276 }
277
278 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 285 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
279 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 286 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
280 m_part.ParentGroup.AddActiveScriptCount(1); 287 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -282,36 +289,31 @@ namespace OpenSim.Region.Framework.Scenes
282 return; 289 return;
283 } 290 }
284 291
285 m_part.ParentGroup.Scene.AssetService.Get( 292 m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
286 item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) 293 {
287 { 294 if (null == asset)
288 if (null == asset) 295 {
289 { 296 m_log.ErrorFormat(
290 m_log.ErrorFormat( 297 "[PRIM INVENTORY]: " +
291 "[PRIM INVENTORY]: " + 298 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
292 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 299 item.Name, item.ItemID, m_part.AbsolutePosition,
293 item.Name, item.ItemID, m_part.AbsolutePosition, 300 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
294 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 301 }
295 } 302 else
296 else 303 {
297 { 304 if (m_part.ParentGroup.m_savedScriptState != null)
298 if (m_part.ParentGroup.m_savedScriptState != null) 305 RestoreSavedScriptState(item.OldItemID, item.ItemID);
299 RestoreSavedScriptState(item.OldItemID, item.ItemID); 306 m_items.LockItemsForWrite(true);
300 307 m_items[item.ItemID].PermsMask = 0;
301 lock (m_items) 308 m_items[item.ItemID].PermsGranter = UUID.Zero;
302 { 309 m_items.LockItemsForWrite(false);
303 m_items[item.ItemID].PermsMask = 0; 310 string script = Utils.BytesToString(asset.Data);
304 m_items[item.ItemID].PermsGranter = UUID.Zero; 311 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
305 } 312 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
306 313 m_part.ParentGroup.AddActiveScriptCount(1);
307 string script = Utils.BytesToString(asset.Data); 314 m_part.ScheduleFullUpdate();
308 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 315 }
309 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 316 });
310 m_part.ParentGroup.AddActiveScriptCount(1);
311 m_part.ScheduleFullUpdate();
312 }
313 }
314 );
315 } 317 }
316 } 318 }
317 319
@@ -378,14 +380,17 @@ namespace OpenSim.Region.Framework.Scenes
378 /// </param> 380 /// </param>
379 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 381 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
380 { 382 {
381 lock (m_items) 383 m_items.LockItemsForRead(true);
384 if (m_items.ContainsKey(itemId))
382 { 385 {
383 if (m_items.ContainsKey(itemId)) 386 if (m_items.ContainsKey(itemId))
384 { 387 {
388 m_items.LockItemsForRead(false);
385 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 389 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
386 } 390 }
387 else 391 else
388 { 392 {
393 m_items.LockItemsForRead(false);
389 m_log.ErrorFormat( 394 m_log.ErrorFormat(
390 "[PRIM INVENTORY]: " + 395 "[PRIM INVENTORY]: " +
391 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 396 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -393,6 +398,15 @@ namespace OpenSim.Region.Framework.Scenes
393 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 398 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
394 } 399 }
395 } 400 }
401 else
402 {
403 m_items.LockItemsForRead(false);
404 m_log.ErrorFormat(
405 "[PRIM INVENTORY]: " +
406 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
407 itemId, m_part.Name, m_part.UUID);
408 }
409
396 } 410 }
397 411
398 /// <summary> 412 /// <summary>
@@ -405,15 +419,7 @@ namespace OpenSim.Region.Framework.Scenes
405 /// </param> 419 /// </param>
406 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 420 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
407 { 421 {
408 bool scriptPresent = false; 422 if (m_items.ContainsKey(itemId))
409
410 lock (m_items)
411 {
412 if (m_items.ContainsKey(itemId))
413 scriptPresent = true;
414 }
415
416 if (scriptPresent)
417 { 423 {
418 if (!sceneObjectBeingDeleted) 424 if (!sceneObjectBeingDeleted)
419 m_part.RemoveScriptEvents(itemId); 425 m_part.RemoveScriptEvents(itemId);
@@ -439,11 +445,16 @@ namespace OpenSim.Region.Framework.Scenes
439 /// <returns></returns> 445 /// <returns></returns>
440 private bool InventoryContainsName(string name) 446 private bool InventoryContainsName(string name)
441 { 447 {
442 foreach (TaskInventoryItem item in Items.Values) 448 m_items.LockItemsForRead(true);
449 foreach (TaskInventoryItem item in m_items.Values)
443 { 450 {
444 if (item.Name == name) 451 if (item.Name == name)
452 {
453 m_items.LockItemsForRead(false);
445 return true; 454 return true;
455 }
446 } 456 }
457 m_items.LockItemsForRead(false);
447 return false; 458 return false;
448 } 459 }
449 460
@@ -485,13 +496,9 @@ namespace OpenSim.Region.Framework.Scenes
485 /// <param name="item"></param> 496 /// <param name="item"></param>
486 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 497 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
487 { 498 {
488 List<TaskInventoryItem> il; 499 m_items.LockItemsForRead(true);
489 500 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
490 lock (m_items) 501 m_items.LockItemsForRead(false);
491 {
492 il = new List<TaskInventoryItem>(m_items.Values);
493 }
494
495 foreach (TaskInventoryItem i in il) 502 foreach (TaskInventoryItem i in il)
496 { 503 {
497 if (i.Name == item.Name) 504 if (i.Name == item.Name)
@@ -528,15 +535,14 @@ namespace OpenSim.Region.Framework.Scenes
528 item.ParentPartID = m_part.UUID; 535 item.ParentPartID = m_part.UUID;
529 item.Name = name; 536 item.Name = name;
530 537
531 lock (m_items) 538 m_items.LockItemsForWrite(true);
532 { 539 m_items.Add(item.ItemID, item);
533 m_items.Add(item.ItemID, item); 540 m_items.LockItemsForWrite(false);
534
535 if (allowedDrop) 541 if (allowedDrop)
536 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 542 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
537 else 543 else
538 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 544 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
539 } 545
540 546
541 m_inventorySerial++; 547 m_inventorySerial++;
542 //m_inventorySerial += 2; 548 //m_inventorySerial += 2;
@@ -553,14 +559,13 @@ namespace OpenSim.Region.Framework.Scenes
553 /// <param name="items"></param> 559 /// <param name="items"></param>
554 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 560 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
555 { 561 {
556 lock (m_items) 562 m_items.LockItemsForWrite(true);
563 foreach (TaskInventoryItem item in items)
557 { 564 {
558 foreach (TaskInventoryItem item in items) 565 m_items.Add(item.ItemID, item);
559 { 566 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
560 m_items.Add(item.ItemID, item);
561 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
562 }
563 } 567 }
568 m_items.LockItemsForWrite(false);
564 569
565 m_inventorySerial++; 570 m_inventorySerial++;
566 } 571 }
@@ -573,10 +578,9 @@ namespace OpenSim.Region.Framework.Scenes
573 public TaskInventoryItem GetInventoryItem(UUID itemId) 578 public TaskInventoryItem GetInventoryItem(UUID itemId)
574 { 579 {
575 TaskInventoryItem item; 580 TaskInventoryItem item;
576 581 m_items.LockItemsForRead(true);
577 lock (m_items) 582 m_items.TryGetValue(itemId, out item);
578 m_items.TryGetValue(itemId, out item); 583 m_items.LockItemsForRead(false);
579
580 return item; 584 return item;
581 } 585 }
582 586
@@ -612,46 +616,46 @@ namespace OpenSim.Region.Framework.Scenes
612 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 616 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
613 public bool UpdateInventoryItem(TaskInventoryItem item) 617 public bool UpdateInventoryItem(TaskInventoryItem item)
614 { 618 {
615 lock (m_items) 619 m_items.LockItemsForWrite(true);
620
621 if (m_items.ContainsKey(item.ItemID))
616 { 622 {
617 if (m_items.ContainsKey(item.ItemID)) 623 item.ParentID = m_part.UUID;
624 item.ParentPartID = m_part.UUID;
625 item.Flags = m_items[item.ItemID].Flags;
626 if (item.AssetID == UUID.Zero)
618 { 627 {
619 item.ParentID = m_part.UUID; 628 item.AssetID = m_items[item.ItemID].AssetID;
620 item.ParentPartID = m_part.UUID; 629 }
621 item.Flags = m_items[item.ItemID].Flags; 630 else if ((InventoryType)item.Type == InventoryType.Notecard)
622 if (item.AssetID == UUID.Zero) 631 {
623 { 632 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
624 item.AssetID = m_items[item.ItemID].AssetID;
625 }
626 else if ((InventoryType)item.Type == InventoryType.Notecard)
627 {
628 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
629 633
630 if (presence != null) 634 if (presence != null)
631 { 635 {
632 presence.ControllingClient.SendAgentAlertMessage( 636 presence.ControllingClient.SendAgentAlertMessage(
633 "Notecard saved", false); 637 "Notecard saved", false);
634 }
635 } 638 }
639 }
636 640
637 m_items[item.ItemID] = item; 641 m_items[item.ItemID] = item;
638 m_inventorySerial++; 642 m_inventorySerial++;
639 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 643 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
640
641 HasInventoryChanged = true;
642 m_part.ParentGroup.HasGroupChanged = true;
643 644
644 return true; 645 HasInventoryChanged = true;
645 } 646 m_part.ParentGroup.HasGroupChanged = true;
646 else 647 m_items.LockItemsForWrite(false);
647 { 648 return true;
648 m_log.ErrorFormat( 649 }
649 "[PRIM INVENTORY]: " + 650 else
650 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 651 {
651 item.ItemID, m_part.Name, m_part.UUID, 652 m_log.ErrorFormat(
652 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 653 "[PRIM INVENTORY]: " +
653 } 654 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
655 item.ItemID, m_part.Name, m_part.UUID,
656 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
654 } 657 }
658 m_items.LockItemsForWrite(false);
655 659
656 return false; 660 return false;
657 } 661 }
@@ -664,53 +668,54 @@ namespace OpenSim.Region.Framework.Scenes
664 /// in this prim's inventory.</returns> 668 /// in this prim's inventory.</returns>
665 public int RemoveInventoryItem(UUID itemID) 669 public int RemoveInventoryItem(UUID itemID)
666 { 670 {
667 lock (m_items) 671 m_items.LockItemsForRead(true);
672
673 if (m_items.ContainsKey(itemID))
668 { 674 {
669 if (m_items.ContainsKey(itemID)) 675 int type = m_items[itemID].InvType;
676 m_items.LockItemsForRead(false);
677 if (type == 10) // Script
670 { 678 {
671 int type = m_items[itemID].InvType; 679 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
672 if (type == 10) // Script 680 }
673 { 681 m_items.LockItemsForWrite(true);
674 m_part.RemoveScriptEvents(itemID); 682 m_items.Remove(itemID);
675 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 683 m_items.LockItemsForWrite(false);
676 } 684 m_inventorySerial++;
677 m_items.Remove(itemID); 685 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
678 m_inventorySerial++;
679 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
680
681 HasInventoryChanged = true;
682 m_part.ParentGroup.HasGroupChanged = true;
683 686
684 int scriptcount = 0; 687 HasInventoryChanged = true;
685 lock (m_items) 688 m_part.ParentGroup.HasGroupChanged = true;
686 {
687 foreach (TaskInventoryItem item in m_items.Values)
688 {
689 if (item.Type == 10)
690 {
691 scriptcount++;
692 }
693 }
694 }
695 689
696 if (scriptcount <= 0) 690 int scriptcount = 0;
691 m_items.LockItemsForRead(true);
692 foreach (TaskInventoryItem item in m_items.Values)
693 {
694 if (item.Type == 10)
697 { 695 {
698 m_part.RemFlag(PrimFlags.Scripted); 696 scriptcount++;
699 } 697 }
700
701 m_part.ScheduleFullUpdate();
702
703 return type;
704 } 698 }
705 else 699 m_items.LockItemsForRead(false);
700
701
702 if (scriptcount <= 0)
706 { 703 {
707 m_log.ErrorFormat( 704 m_part.RemFlag(PrimFlags.Scripted);
708 "[PRIM INVENTORY]: " +
709 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
710 itemID, m_part.Name, m_part.UUID,
711 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
712 } 705 }
706
707 m_part.ScheduleFullUpdate();
708
709 return type;
710 }
711 else
712 {
713 m_log.ErrorFormat(
714 "[PRIM INVENTORY]: " +
715 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
716 itemID, m_part.Name, m_part.UUID);
713 } 717 }
718 m_items.LockItemsForWrite(false);
714 719
715 return -1; 720 return -1;
716 } 721 }
@@ -763,52 +768,53 @@ namespace OpenSim.Region.Framework.Scenes
763 // isn't available (such as drag from prim inventory to agent inventory) 768 // isn't available (such as drag from prim inventory to agent inventory)
764 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 769 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
765 770
766 lock (m_items) 771 m_items.LockItemsForRead(true);
772
773 foreach (TaskInventoryItem item in m_items.Values)
767 { 774 {
768 foreach (TaskInventoryItem item in m_items.Values) 775 UUID ownerID = item.OwnerID;
769 { 776 uint everyoneMask = 0;
770 UUID ownerID = item.OwnerID; 777 uint baseMask = item.BasePermissions;
771 uint everyoneMask = 0; 778 uint ownerMask = item.CurrentPermissions;
772 uint baseMask = item.BasePermissions;
773 uint ownerMask = item.CurrentPermissions;
774 779
775 invString.AddItemStart(); 780 invString.AddItemStart();
776 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 781 invString.AddNameValueLine("item_id", item.ItemID.ToString());
777 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 782 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
778 783
779 invString.AddPermissionsStart(); 784 invString.AddPermissionsStart();
780 785
781 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 786 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
782 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 787 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
783 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 788 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
784 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 789 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
785 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 790 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
786 791
787 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 792 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
788 invString.AddNameValueLine("owner_id", ownerID.ToString()); 793 invString.AddNameValueLine("owner_id", ownerID.ToString());
789 794
790 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 795 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
791 796
792 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 797 invString.AddNameValueLine("group_id", item.GroupID.ToString());
793 invString.AddSectionEnd(); 798 invString.AddSectionEnd();
794 799
795 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 800 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
796 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 801 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
797 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 802 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
798 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 803 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
799 804
800 invString.AddSaleStart(); 805 invString.AddSaleStart();
801 invString.AddNameValueLine("sale_type", "not"); 806 invString.AddNameValueLine("sale_type", "not");
802 invString.AddNameValueLine("sale_price", "0"); 807 invString.AddNameValueLine("sale_price", "0");
803 invString.AddSectionEnd(); 808 invString.AddSectionEnd();
804 809
805 invString.AddNameValueLine("name", item.Name + "|"); 810 invString.AddNameValueLine("name", item.Name + "|");
806 invString.AddNameValueLine("desc", item.Description + "|"); 811 invString.AddNameValueLine("desc", item.Description + "|");
807 812
808 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 813 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
809 invString.AddSectionEnd(); 814 invString.AddSectionEnd();
810 }
811 } 815 }
816 int count = m_items.Count;
817 m_items.LockItemsForRead(false);
812 818
813 fileData = Utils.StringToBytes(invString.BuildString); 819 fileData = Utils.StringToBytes(invString.BuildString);
814 820
@@ -829,10 +835,9 @@ namespace OpenSim.Region.Framework.Scenes
829 { 835 {
830 if (HasInventoryChanged) 836 if (HasInventoryChanged)
831 { 837 {
832 lock (Items) 838 Items.LockItemsForRead(true);
833 { 839 datastore.StorePrimInventory(m_part.UUID, Items.Values);
834 datastore.StorePrimInventory(m_part.UUID, Items.Values); 840 Items.LockItemsForRead(false);
835 }
836 841
837 HasInventoryChanged = false; 842 HasInventoryChanged = false;
838 } 843 }
@@ -901,61 +906,54 @@ namespace OpenSim.Region.Framework.Scenes
901 { 906 {
902 uint mask=0x7fffffff; 907 uint mask=0x7fffffff;
903 908
904 lock (m_items) 909 foreach (TaskInventoryItem item in m_items.Values)
905 { 910 {
906 foreach (TaskInventoryItem item in m_items.Values) 911 if (item.InvType != (int)InventoryType.Object)
907 { 912 {
908 if (item.InvType != (int)InventoryType.Object) 913 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
909 { 914 mask &= ~((uint)PermissionMask.Copy >> 13);
910 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 915 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
911 mask &= ~((uint)PermissionMask.Copy >> 13); 916 mask &= ~((uint)PermissionMask.Transfer >> 13);
912 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 917 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
913 mask &= ~((uint)PermissionMask.Transfer >> 13); 918 mask &= ~((uint)PermissionMask.Modify >> 13);
914 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 919 }
915 mask &= ~((uint)PermissionMask.Modify >> 13); 920 else
916 } 921 {
917 else 922 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
918 { 923 mask &= ~((uint)PermissionMask.Copy >> 13);
919 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 924 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
920 mask &= ~((uint)PermissionMask.Copy >> 13); 925 mask &= ~((uint)PermissionMask.Transfer >> 13);
921 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 926 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
922 mask &= ~((uint)PermissionMask.Transfer >> 13); 927 mask &= ~((uint)PermissionMask.Modify >> 13);
923 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
924 mask &= ~((uint)PermissionMask.Modify >> 13);
925 }
926
927 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
928 mask &= ~(uint)PermissionMask.Copy;
929 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
930 mask &= ~(uint)PermissionMask.Transfer;
931 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
932 mask &= ~(uint)PermissionMask.Modify;
933 } 928 }
929
930 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
931 mask &= ~(uint)PermissionMask.Copy;
932 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
933 mask &= ~(uint)PermissionMask.Transfer;
934 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
935 mask &= ~(uint)PermissionMask.Modify;
934 } 936 }
935
936 return mask; 937 return mask;
937 } 938 }
938 939
939 public void ApplyNextOwnerPermissions() 940 public void ApplyNextOwnerPermissions()
940 { 941 {
941 lock (m_items) 942 foreach (TaskInventoryItem item in m_items.Values)
942 { 943 {
943 foreach (TaskInventoryItem item in m_items.Values) 944 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
944 { 945 {
945 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 946 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
946 { 947 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
947 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 948 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
948 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 949 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
949 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 950 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
950 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 951 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
951 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 952 item.CurrentPermissions |= 8;
952 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
953 item.CurrentPermissions |= 8;
954 }
955 item.CurrentPermissions &= item.NextPermissions;
956 item.BasePermissions &= item.NextPermissions;
957 item.EveryonePermissions &= item.NextPermissions;
958 } 953 }
954 item.CurrentPermissions &= item.NextPermissions;
955 item.BasePermissions &= item.NextPermissions;
956 item.EveryonePermissions &= item.NextPermissions;
959 } 957 }
960 958
961 m_part.TriggerScriptChangedEvent(Changed.OWNER); 959 m_part.TriggerScriptChangedEvent(Changed.OWNER);
@@ -963,29 +961,22 @@ namespace OpenSim.Region.Framework.Scenes
963 961
964 public void ApplyGodPermissions(uint perms) 962 public void ApplyGodPermissions(uint perms)
965 { 963 {
966 lock (m_items) 964 foreach (TaskInventoryItem item in m_items.Values)
967 { 965 {
968 foreach (TaskInventoryItem item in m_items.Values) 966 item.CurrentPermissions = perms;
969 { 967 item.BasePermissions = perms;
970 item.CurrentPermissions = perms;
971 item.BasePermissions = perms;
972 }
973 } 968 }
974 } 969 }
975 970
976 public bool ContainsScripts() 971 public bool ContainsScripts()
977 { 972 {
978 lock (m_items) 973 foreach (TaskInventoryItem item in m_items.Values)
979 { 974 {
980 foreach (TaskInventoryItem item in m_items.Values) 975 if (item.InvType == (int)InventoryType.LSL)
981 { 976 {
982 if (item.InvType == (int)InventoryType.LSL) 977 return true;
983 {
984 return true;
985 }
986 } 978 }
987 } 979 }
988
989 return false; 980 return false;
990 } 981 }
991 982
@@ -993,11 +984,8 @@ namespace OpenSim.Region.Framework.Scenes
993 { 984 {
994 List<UUID> ret = new List<UUID>(); 985 List<UUID> ret = new List<UUID>();
995 986
996 lock (m_items) 987 foreach (TaskInventoryItem item in m_items.Values)
997 { 988 ret.Add(item.ItemID);
998 foreach (TaskInventoryItem item in m_items.Values)
999 ret.Add(item.ItemID);
1000 }
1001 989
1002 return ret; 990 return ret;
1003 } 991 }
@@ -1010,30 +998,26 @@ namespace OpenSim.Region.Framework.Scenes
1010 if (engines == null) // No engine at all 998 if (engines == null) // No engine at all
1011 return ret; 999 return ret;
1012 1000
1013 lock (m_items) 1001 foreach (TaskInventoryItem item in m_items.Values)
1014 { 1002 {
1015 foreach (TaskInventoryItem item in m_items.Values) 1003 if (item.InvType == (int)InventoryType.LSL)
1016 { 1004 {
1017 if (item.InvType == (int)InventoryType.LSL) 1005 foreach (IScriptModule e in engines)
1018 { 1006 {
1019 foreach (IScriptModule e in engines) 1007 if (e != null)
1020 { 1008 {
1021 if (e != null) 1009 string n = e.GetXMLState(item.ItemID);
1010 if (n != String.Empty)
1022 { 1011 {
1023 string n = e.GetXMLState(item.ItemID); 1012 if (!ret.ContainsKey(item.ItemID))
1024 if (n != String.Empty) 1013 ret[item.ItemID] = n;
1025 { 1014 break;
1026 if (!ret.ContainsKey(item.ItemID))
1027 ret[item.ItemID] = n;
1028 break;
1029 }
1030 } 1015 }
1031 } 1016 }
1032 } 1017 }
1033 } 1018 }
1034 } 1019 }
1035
1036 return ret; 1020 return ret;
1037 } 1021 }
1038 } 1022 }
1039} \ No newline at end of file 1023}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f83a4d2..453523a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -123,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
126 128
127 private Vector3 m_lastPosition; 129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -134,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 140 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 141 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 142
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 143 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 144
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -182,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
182 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
183 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
184 187
185 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
186 190
187 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
188 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -207,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
208 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
209 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
210 215
211 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
212 217
@@ -217,6 +222,9 @@ namespace OpenSim.Region.Framework.Scenes
217 private bool m_followCamAuto; 222 private bool m_followCamAuto;
218 223
219 private int m_movementUpdateCount; 224 private int m_movementUpdateCount;
225 private int m_lastColCount = -1; //KF: Look for Collision chnages
226 private int m_updateCount = 0; //KF: Update Anims for a while
227 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
220 228
221 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
222 230
@@ -245,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 260 }
251 261
@@ -682,10 +692,7 @@ namespace OpenSim.Region.Framework.Scenes
682 m_reprioritization_timer.AutoReset = false; 692 m_reprioritization_timer.AutoReset = false;
683 693
684 AdjustKnownSeeds(); 694 AdjustKnownSeeds();
685
686 // TODO: I think, this won't send anything, as we are still a child here...
687 Animator.TrySetMovementAnimation("STAND"); 695 Animator.TrySetMovementAnimation("STAND");
688
689 // we created a new ScenePresence (a new child agent) in a fresh region. 696 // we created a new ScenePresence (a new child agent) in a fresh region.
690 // Request info about all the (root) agents in this region 697 // Request info about all the (root) agents in this region
691 // Note: This won't send data *to* other clients in that region (children don't send) 698 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -741,25 +748,47 @@ namespace OpenSim.Region.Framework.Scenes
741 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 748 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
742 Dir_Vectors[4] = Vector3.UnitZ; //UP 749 Dir_Vectors[4] = Vector3.UnitZ; //UP
743 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 750 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
744 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 751 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
745 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 752 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
746 Dir_Vectors[7] = -Vector3.UnitX; //BACK 753 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
754 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
755 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
747 } 756 }
748 757
749 private Vector3[] GetWalkDirectionVectors() 758 private Vector3[] GetWalkDirectionVectors()
750 { 759 {
751 Vector3[] vector = new Vector3[9]; 760 Vector3[] vector = new Vector3[11];
752 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 761 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
753 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 762 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
754 vector[2] = Vector3.UnitY; //LEFT 763 vector[2] = Vector3.UnitY; //LEFT
755 vector[3] = -Vector3.UnitY; //RIGHT 764 vector[3] = -Vector3.UnitY; //RIGHT
756 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 765 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
757 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 766 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
758 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 767 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
759 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 768 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
760 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 769 vector[8] = Vector3.UnitY; //LEFT_NUDGE
770 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
771 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
761 return vector; 772 return vector;
762 } 773 }
774
775 private bool[] GetDirectionIsNudge()
776 {
777 bool[] isNudge = new bool[11];
778 isNudge[0] = false; //FORWARD
779 isNudge[1] = false; //BACK
780 isNudge[2] = false; //LEFT
781 isNudge[3] = false; //RIGHT
782 isNudge[4] = false; //UP
783 isNudge[5] = false; //DOWN
784 isNudge[6] = true; //FORWARD_NUDGE
785 isNudge[7] = true; //BACK_NUDGE
786 isNudge[8] = true; //LEFT_NUDGE
787 isNudge[9] = true; //RIGHT_NUDGE
788 isNudge[10] = true; //DOWN_Nudge
789 return isNudge;
790 }
791
763 792
764 #endregion 793 #endregion
765 794
@@ -828,9 +857,24 @@ namespace OpenSim.Region.Framework.Scenes
828 { 857 {
829 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 858 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
830 pos.Y = crossedBorder.BorderLine.Z - 1; 859 pos.Y = crossedBorder.BorderLine.Z - 1;
860 }
861
862 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
863 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
864 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
865 if (KnownChildRegionHandles.Count == 0)
866 {
867 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
868 if (land != null)
869 {
870 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
871 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)
872 {
873 pos = land.LandData.UserLocation;
874 }
875 }
831 } 876 }
832 877
833
834 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 878 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
835 { 879 {
836 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 880 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -990,9 +1034,10 @@ namespace OpenSim.Region.Framework.Scenes
990 public void Teleport(Vector3 pos) 1034 public void Teleport(Vector3 pos)
991 { 1035 {
992 bool isFlying = false; 1036 bool isFlying = false;
993 if (m_physicsActor != null)
994 isFlying = m_physicsActor.Flying;
995 1037
1038 if (m_physicsActor != null)
1039 isFlying = m_physicsActor.Flying;
1040
996 RemoveFromPhysicalScene(); 1041 RemoveFromPhysicalScene();
997 Velocity = Vector3.Zero; 1042 Velocity = Vector3.Zero;
998 AbsolutePosition = pos; 1043 AbsolutePosition = pos;
@@ -1003,7 +1048,8 @@ namespace OpenSim.Region.Framework.Scenes
1003 SetHeight(m_appearance.AvatarHeight); 1048 SetHeight(m_appearance.AvatarHeight);
1004 } 1049 }
1005 1050
1006 SendTerseUpdateToAllClients(); 1051 SendTerseUpdateToAllClients();
1052
1007 } 1053 }
1008 1054
1009 public void TeleportWithMomentum(Vector3 pos) 1055 public void TeleportWithMomentum(Vector3 pos)
@@ -1048,7 +1094,9 @@ namespace OpenSim.Region.Framework.Scenes
1048 { 1094 {
1049 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1095 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1050 } 1096 }
1051 1097
1098 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1099
1052 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1100 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1053 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1101 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1054 } 1102 }
@@ -1299,7 +1347,6 @@ namespace OpenSim.Region.Framework.Scenes
1299 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1347 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1300 } 1348 }
1301 } 1349 }
1302
1303 lock (scriptedcontrols) 1350 lock (scriptedcontrols)
1304 { 1351 {
1305 if (scriptedcontrols.Count > 0) 1352 if (scriptedcontrols.Count > 0)
@@ -1314,12 +1361,8 @@ namespace OpenSim.Region.Framework.Scenes
1314 1361
1315 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1362 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1316 { 1363 {
1317 // TODO: This doesn't prevent the user from walking yet. 1364 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1318 // Setting parent ID would fix this, if we knew what value 1365 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1319 // to use. Or we could add a m_isSitting variable.
1320 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1321 SitGround = true;
1322
1323 } 1366 }
1324 1367
1325 // In the future, these values might need to go global. 1368 // In the future, these values might need to go global.
@@ -1369,6 +1412,11 @@ namespace OpenSim.Region.Framework.Scenes
1369 update_rotation = true; 1412 update_rotation = true;
1370 } 1413 }
1371 1414
1415 //guilty until proven innocent..
1416 bool Nudging = true;
1417 //Basically, if there is at least one non-nudge control then we don't need
1418 //to worry about stopping the avatar
1419
1372 if (m_parentID == 0) 1420 if (m_parentID == 0)
1373 { 1421 {
1374 bool bAllowUpdateMoveToPosition = false; 1422 bool bAllowUpdateMoveToPosition = false;
@@ -1383,9 +1431,12 @@ namespace OpenSim.Region.Framework.Scenes
1383 else 1431 else
1384 dirVectors = Dir_Vectors; 1432 dirVectors = Dir_Vectors;
1385 1433
1386 // The fact that m_movementflag is a byte needs to be fixed 1434 bool[] isNudge = GetDirectionIsNudge();
1387 // it really should be a uint 1435
1388 uint nudgehack = 250; 1436
1437
1438
1439
1389 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1440 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1390 { 1441 {
1391 if (((uint)flags & (uint)DCF) != 0) 1442 if (((uint)flags & (uint)DCF) != 0)
@@ -1395,40 +1446,28 @@ namespace OpenSim.Region.Framework.Scenes
1395 try 1446 try
1396 { 1447 {
1397 agent_control_v3 += dirVectors[i]; 1448 agent_control_v3 += dirVectors[i];
1398 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1449 if (isNudge[i] == false)
1450 {
1451 Nudging = false;
1452 }
1399 } 1453 }
1400 catch (IndexOutOfRangeException) 1454 catch (IndexOutOfRangeException)
1401 { 1455 {
1402 // Why did I get this? 1456 // Why did I get this?
1403 } 1457 }
1404 1458
1405 if ((m_movementflag & (byte)(uint)DCF) == 0) 1459 if ((m_movementflag & (uint)DCF) == 0)
1406 { 1460 {
1407 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1408 {
1409 m_movementflag |= (byte)nudgehack;
1410 }
1411 m_movementflag += (byte)(uint)DCF; 1461 m_movementflag += (byte)(uint)DCF;
1412 update_movementflag = true; 1462 update_movementflag = true;
1413 } 1463 }
1414 } 1464 }
1415 else 1465 else
1416 { 1466 {
1417 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1467 if ((m_movementflag & (uint)DCF) != 0)
1418 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1419 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1420 ) // This or is for Nudge forward
1421 { 1468 {
1422 m_movementflag -= ((byte)(uint)DCF); 1469 m_movementflag -= (byte)(uint)DCF;
1423
1424 update_movementflag = true; 1470 update_movementflag = true;
1425 /*
1426 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1427 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1428 {
1429 m_log.Debug("Removed Hack flag");
1430 }
1431 */
1432 } 1471 }
1433 else 1472 else
1434 { 1473 {
@@ -1472,6 +1511,9 @@ namespace OpenSim.Region.Framework.Scenes
1472 // Ignore z component of vector 1511 // Ignore z component of vector
1473 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1512 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1474 LocalVectorToTarget2D.Normalize(); 1513 LocalVectorToTarget2D.Normalize();
1514
1515 //We're not nudging
1516 Nudging = false;
1475 agent_control_v3 += LocalVectorToTarget2D; 1517 agent_control_v3 += LocalVectorToTarget2D;
1476 1518
1477 // update avatar movement flags. the avatar coordinate system is as follows: 1519 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1560,13 +1602,13 @@ namespace OpenSim.Region.Framework.Scenes
1560 // m_log.DebugFormat( 1602 // m_log.DebugFormat(
1561 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1603 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1562 1604
1563 AddNewMovement(agent_control_v3, q); 1605 AddNewMovement(agent_control_v3, q, Nudging);
1564 1606
1565 1607
1566 } 1608 }
1567 } 1609 }
1568 1610
1569 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1611 if (update_movementflag)
1570 Animator.UpdateMovementAnimations(); 1612 Animator.UpdateMovementAnimations();
1571 1613
1572 m_scene.EventManager.TriggerOnClientMovement(this); 1614 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1581,7 +1623,6 @@ namespace OpenSim.Region.Framework.Scenes
1581 m_sitAtAutoTarget = false; 1623 m_sitAtAutoTarget = false;
1582 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1624 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1583 //proxy.PCode = (byte)PCode.ParticleSystem; 1625 //proxy.PCode = (byte)PCode.ParticleSystem;
1584
1585 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1626 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1586 proxyObjectGroup.AttachToScene(m_scene); 1627 proxyObjectGroup.AttachToScene(m_scene);
1587 1628
@@ -1623,7 +1664,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 } 1664 }
1624 m_moveToPositionInProgress = true; 1665 m_moveToPositionInProgress = true;
1625 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1666 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1626 } 1667 }
1627 catch (Exception ex) 1668 catch (Exception ex)
1628 { 1669 {
1629 //Why did I get this error? 1670 //Why did I get this error?
@@ -1645,7 +1686,7 @@ namespace OpenSim.Region.Framework.Scenes
1645 Velocity = Vector3.Zero; 1686 Velocity = Vector3.Zero;
1646 SendFullUpdateToAllClients(); 1687 SendFullUpdateToAllClients();
1647 1688
1648 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1689 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1649 } 1690 }
1650 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1691 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1651 m_requestedSitTargetUUID = UUID.Zero; 1692 m_requestedSitTargetUUID = UUID.Zero;
@@ -1678,55 +1719,84 @@ namespace OpenSim.Region.Framework.Scenes
1678 /// </summary> 1719 /// </summary>
1679 public void StandUp() 1720 public void StandUp()
1680 { 1721 {
1681 if (SitGround)
1682 SitGround = false;
1683
1684 if (m_parentID != 0) 1722 if (m_parentID != 0)
1685 { 1723 {
1686 m_log.Debug("StandupCode Executed");
1687 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1724 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1688 if (part != null) 1725 if (part != null)
1689 { 1726 {
1727 part.TaskInventory.LockItemsForRead(true);
1690 TaskInventoryDictionary taskIDict = part.TaskInventory; 1728 TaskInventoryDictionary taskIDict = part.TaskInventory;
1691 if (taskIDict != null) 1729 if (taskIDict != null)
1692 { 1730 {
1693 lock (taskIDict) 1731 foreach (UUID taskID in taskIDict.Keys)
1694 { 1732 {
1695 foreach (UUID taskID in taskIDict.Keys) 1733 UnRegisterControlEventsToScript(LocalId, taskID);
1696 { 1734 taskIDict[taskID].PermsMask &= ~(
1697 UnRegisterControlEventsToScript(LocalId, taskID); 1735 2048 | //PERMISSION_CONTROL_CAMERA
1698 taskIDict[taskID].PermsMask &= ~( 1736 4); // PERMISSION_TAKE_CONTROLS
1699 2048 | //PERMISSION_CONTROL_CAMERA
1700 4); // PERMISSION_TAKE_CONTROLS
1701 }
1702 } 1737 }
1703
1704 } 1738 }
1739 part.TaskInventory.LockItemsForRead(false);
1705 // Reset sit target. 1740 // Reset sit target.
1706 if (part.GetAvatarOnSitTarget() == UUID) 1741 if (part.GetAvatarOnSitTarget() == UUID)
1707 part.SetAvatarOnSitTarget(UUID.Zero); 1742 part.SetAvatarOnSitTarget(UUID.Zero);
1708
1709 m_parentPosition = part.GetWorldPosition(); 1743 m_parentPosition = part.GetWorldPosition();
1710 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1744 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1711 } 1745 }
1712 1746 // part.GetWorldRotation() is the rotation of the object being sat on
1713 if (m_physicsActor == null) 1747 // Rotation is the sittiing Av's rotation
1714 { 1748
1715 AddToPhysicalScene(false); 1749 Quaternion partRot;
1750// if (part.LinkNum == 1)
1751// { // Root prim of linkset
1752// partRot = part.ParentGroup.RootPart.RotationOffset;
1753// }
1754// else
1755// { // single or child prim
1756
1757// }
1758 if (part == null) //CW: Part may be gone. llDie() for example.
1759 {
1760 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1761 }
1762 else
1763 {
1764 partRot = part.GetWorldRotation();
1716 } 1765 }
1717 1766
1718 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1767 Quaternion partIRot = Quaternion.Inverse(partRot);
1719 m_parentPosition = Vector3.Zero; 1768
1769 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1770 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1720 1771
1721 m_parentID = 0; 1772
1773 if (m_physicsActor == null)
1774 {
1775 AddToPhysicalScene(false);
1776 }
1777 //CW: If the part isn't null then we can set the current position
1778 if (part != null)
1779 {
1780 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1781 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1782 part.IsOccupied = false;
1783 }
1784 else
1785 {
1786 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1787 AbsolutePosition = m_lastWorldPosition;
1788 }
1789
1790 m_parentPosition = Vector3.Zero;
1791 m_parentID = 0;
1722 SendFullUpdateToAllClients(); 1792 SendFullUpdateToAllClients();
1723 m_requestedSitTargetID = 0; 1793 m_requestedSitTargetID = 0;
1794
1724 if ((m_physicsActor != null) && (m_avHeight > 0)) 1795 if ((m_physicsActor != null) && (m_avHeight > 0))
1725 { 1796 {
1726 SetHeight(m_avHeight); 1797 SetHeight(m_avHeight);
1727 } 1798 }
1728 } 1799 }
1729
1730 Animator.TrySetMovementAnimation("STAND"); 1800 Animator.TrySetMovementAnimation("STAND");
1731 } 1801 }
1732 1802
@@ -1757,13 +1827,9 @@ namespace OpenSim.Region.Framework.Scenes
1757 Vector3 avSitOffSet = part.SitTargetPosition; 1827 Vector3 avSitOffSet = part.SitTargetPosition;
1758 Quaternion avSitOrientation = part.SitTargetOrientation; 1828 Quaternion avSitOrientation = part.SitTargetOrientation;
1759 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1829 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1760 1830 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1761 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1831 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1762 bool SitTargetisSet = 1832 if (SitTargetisSet && !SitTargetOccupied)
1763 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1764 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1765
1766 if (SitTargetisSet && SitTargetUnOccupied)
1767 { 1833 {
1768 //switch the target to this prim 1834 //switch the target to this prim
1769 return part; 1835 return part;
@@ -1777,84 +1843,152 @@ namespace OpenSim.Region.Framework.Scenes
1777 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1843 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1778 { 1844 {
1779 bool autopilot = true; 1845 bool autopilot = true;
1846 Vector3 autopilotTarget = new Vector3();
1847 Quaternion sitOrientation = Quaternion.Identity;
1780 Vector3 pos = new Vector3(); 1848 Vector3 pos = new Vector3();
1781 Quaternion sitOrientation = pSitOrientation;
1782 Vector3 cameraEyeOffset = Vector3.Zero; 1849 Vector3 cameraEyeOffset = Vector3.Zero;
1783 Vector3 cameraAtOffset = Vector3.Zero; 1850 Vector3 cameraAtOffset = Vector3.Zero;
1784 bool forceMouselook = false; 1851 bool forceMouselook = false;
1785 1852
1786 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1853 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1787 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1854 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1788 if (part != null) 1855 if (part == null) return;
1789 { 1856
1790 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1857 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1791 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1858 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1792 1859
1793 // Is a sit target available? 1860 // part is the prim to sit on
1794 Vector3 avSitOffSet = part.SitTargetPosition; 1861 // offset is the world-ref vector distance from that prim center to the click-spot
1795 Quaternion avSitOrientation = part.SitTargetOrientation; 1862 // UUID is the UUID of the Avatar doing the clicking
1796 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1863
1797 1864 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1798 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1865
1799 bool SitTargetisSet = 1866 // Is a sit target available?
1800 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1867 Vector3 avSitOffSet = part.SitTargetPosition;
1801 ( 1868 Quaternion avSitOrientation = part.SitTargetOrientation;
1802 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1869
1803 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1870 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1804 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1871 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1805 ) 1872 Quaternion partRot;
1806 )); 1873// if (part.LinkNum == 1)
1807 1874// { // Root prim of linkset
1808 if (SitTargetisSet && SitTargetUnOccupied) 1875// partRot = part.ParentGroup.RootPart.RotationOffset;
1809 { 1876// }
1810 part.SetAvatarOnSitTarget(UUID); 1877// else
1811 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1878// { // single or child prim
1812 sitOrientation = avSitOrientation; 1879 partRot = part.GetWorldRotation();
1813 autopilot = false; 1880// }
1814 } 1881 Quaternion partIRot = Quaternion.Inverse(partRot);
1815 1882//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1816 pos = part.AbsolutePosition + offset; 1883 // Sit analysis rewritten by KF 091125
1817 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1884 if (SitTargetisSet) // scipted sit
1818 //{ 1885 {
1819 // offset = pos; 1886 if (!part.IsOccupied)
1820 //autopilot = false; 1887 {
1821 //} 1888//Console.WriteLine("Scripted, unoccupied");
1822 if (m_physicsActor != null) 1889 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1823 { 1890 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1824 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1891 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1825 // We can remove the physicsActor until they stand up. 1892 autopilot = false; // Jump direct to scripted llSitPos()
1826 m_sitAvatarHeight = m_physicsActor.Size.Z; 1893 }
1827 1894 else
1828 if (autopilot) 1895 {
1829 { 1896//Console.WriteLine("Scripted, occupied");
1830 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1897 return;
1831 { 1898 }
1832 autopilot = false; 1899 }
1900 else // Not Scripted
1901 {
1902 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1903 {
1904 // large prim & offset, ignore if other Avs sitting
1905// offset.Z -= 0.05f;
1906 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1907 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1908
1909//Console.WriteLine(" offset ={0}", offset);
1910//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1911//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1912
1913 }
1914 else // small offset
1915 {
1916//Console.WriteLine("Small offset");
1917 if (!part.IsOccupied)
1918 {
1919 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1920 autopilotTarget = part.AbsolutePosition;
1921 }
1922 else return; // occupied small
1923 } // end large/small
1924 } // end Scripted/not
1925 cameraAtOffset = part.GetCameraAtOffset();
1926 cameraEyeOffset = part.GetCameraEyeOffset();
1927 forceMouselook = part.GetForceMouselook();
1928 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1929 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1833 1930
1834 RemoveFromPhysicalScene(); 1931 if (m_physicsActor != null)
1835 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1932 {
1836 } 1933 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1837 } 1934 // We can remove the physicsActor until they stand up.
1838 else 1935 m_sitAvatarHeight = m_physicsActor.Size.Z;
1936 if (autopilot)
1937 { // its not a scripted sit
1938// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1939 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1839 { 1940 {
1941 autopilot = false; // close enough
1942 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1943 Not using the part's position because returning the AV to the last known standing
1944 position is likely to be more friendly, isn't it? */
1840 RemoveFromPhysicalScene(); 1945 RemoveFromPhysicalScene();
1841 } 1946 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1947 } // else the autopilot will get us close
1948 }
1949 else
1950 { // its a scripted sit
1951 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1952 I *am* using the part's position this time because we have no real idea how far away
1953 the avatar is from the sit target. */
1954 RemoveFromPhysicalScene();
1842 } 1955 }
1843
1844 cameraAtOffset = part.GetCameraAtOffset();
1845 cameraEyeOffset = part.GetCameraEyeOffset();
1846 forceMouselook = part.GetForceMouselook();
1847 } 1956 }
1848 1957 else return; // physactor is null!
1849 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1958
1850 m_requestedSitTargetUUID = targetID; 1959 Vector3 offsetr; // = offset * partIRot;
1960 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1961 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1962 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1963 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1964 offsetr = offset * partIRot;
1965//
1966 // else
1967 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1968 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1969 // (offset * partRot);
1970 // }
1971
1972//Console.WriteLine(" ");
1973//Console.WriteLine("link number ={0}", part.LinkNum);
1974//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1975//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1976//Console.WriteLine("Click offst ={0}", offset);
1977//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1978//Console.WriteLine("offsetr ={0}", offsetr);
1979//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1980//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1981
1982 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1983 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1851 // This calls HandleAgentSit twice, once from here, and the client calls 1984 // This calls HandleAgentSit twice, once from here, and the client calls
1852 // HandleAgentSit itself after it gets to the location 1985 // HandleAgentSit itself after it gets to the location
1853 // It doesn't get to the location until we've moved them there though 1986 // It doesn't get to the location until we've moved them there though
1854 // which happens in HandleAgentSit :P 1987 // which happens in HandleAgentSit :P
1855 m_autopilotMoving = autopilot; 1988 m_autopilotMoving = autopilot;
1856 m_autoPilotTarget = pos; 1989 m_autoPilotTarget = autopilotTarget;
1857 m_sitAtAutoTarget = autopilot; 1990 m_sitAtAutoTarget = autopilot;
1991 m_initialSitTarget = autopilotTarget;
1858 if (!autopilot) 1992 if (!autopilot)
1859 HandleAgentSit(remoteClient, UUID); 1993 HandleAgentSit(remoteClient, UUID);
1860 } 1994 }
@@ -2149,31 +2283,65 @@ namespace OpenSim.Region.Framework.Scenes
2149 { 2283 {
2150 if (part != null) 2284 if (part != null)
2151 { 2285 {
2286//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2152 if (part.GetAvatarOnSitTarget() == UUID) 2287 if (part.GetAvatarOnSitTarget() == UUID)
2153 { 2288 {
2289//Console.WriteLine("Scripted Sit");
2290 // Scripted sit
2154 Vector3 sitTargetPos = part.SitTargetPosition; 2291 Vector3 sitTargetPos = part.SitTargetPosition;
2155 Quaternion sitTargetOrient = part.SitTargetOrientation; 2292 Quaternion sitTargetOrient = part.SitTargetOrientation;
2156
2157 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2158 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2159
2160 //Quaternion result = (sitTargetOrient * vq) * nq;
2161
2162 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2293 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2163 m_pos += SIT_TARGET_ADJUSTMENT; 2294 m_pos += SIT_TARGET_ADJUSTMENT;
2164 m_bodyRot = sitTargetOrient; 2295 m_bodyRot = sitTargetOrient;
2165 //Rotation = sitTargetOrient;
2166 m_parentPosition = part.AbsolutePosition; 2296 m_parentPosition = part.AbsolutePosition;
2167 2297 part.IsOccupied = true;
2168 //SendTerseUpdateToAllClients();
2169 } 2298 }
2170 else 2299 else
2171 { 2300 {
2172 m_pos -= part.AbsolutePosition; 2301 // if m_avUnscriptedSitPos is zero then Av sits above center
2302 // Else Av sits at m_avUnscriptedSitPos
2303
2304 // Non-scripted sit by Kitto Flora 21Nov09
2305 // Calculate angle of line from prim to Av
2306 Quaternion partIRot;
2307// if (part.LinkNum == 1)
2308// { // Root prim of linkset
2309// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2310// }
2311// else
2312// { // single or child prim
2313 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2314// }
2315 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2316 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2317 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2318 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2319 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2320 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2321 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2322 // Av sits at world euler <0,0, z>, translated by part rotation
2323 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2324
2173 m_parentPosition = part.AbsolutePosition; 2325 m_parentPosition = part.AbsolutePosition;
2174 } 2326 part.IsOccupied = true;
2327 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2328 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2329 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2330 m_avUnscriptedSitPos; // adds click offset, if any
2331 //Set up raytrace to find top surface of prim
2332 Vector3 size = part.Scale;
2333 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2334 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2335 Vector3 down = new Vector3(0f, 0f, -1f);
2336//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2337 m_scene.PhysicsScene.RaycastWorld(
2338 start, // Vector3 position,
2339 down, // Vector3 direction,
2340 mag, // float length,
2341 SitAltitudeCallback); // retMethod
2342 } // end scripted/not
2175 } 2343 }
2176 else 2344 else // no Av
2177 { 2345 {
2178 return; 2346 return;
2179 } 2347 }
@@ -2185,11 +2353,36 @@ namespace OpenSim.Region.Framework.Scenes
2185 2353
2186 Animator.TrySetMovementAnimation(sitAnimation); 2354 Animator.TrySetMovementAnimation(sitAnimation);
2187 SendFullUpdateToAllClients(); 2355 SendFullUpdateToAllClients();
2188 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2189 // So we're also sending a terse update (which has avatar rotation)
2190 // [Update] We do now.
2191 //SendTerseUpdateToAllClients();
2192 } 2356 }
2357
2358 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2359 {
2360 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2361 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2362 if(hitYN)
2363 {
2364 // m_pos = Av offset from prim center to make look like on center
2365 // m_parentPosition = Actual center pos of prim
2366 // collisionPoint = spot on prim where we want to sit
2367 // collisionPoint.Z = global sit surface height
2368 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2369 Quaternion partIRot;
2370// if (part.LinkNum == 1)
2371/// { // Root prim of linkset
2372// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2373// }
2374// else
2375// { // single or child prim
2376 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2377// }
2378 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2379 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2380//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2381 m_pos += offset;
2382// ControllingClient.SendClearFollowCamProperties(part.UUID);
2383
2384 }
2385 } // End SitAltitudeCallback KF.
2193 2386
2194 /// <summary> 2387 /// <summary>
2195 /// Event handler for the 'Always run' setting on the client 2388 /// Event handler for the 'Always run' setting on the client
@@ -2219,7 +2412,7 @@ namespace OpenSim.Region.Framework.Scenes
2219 /// </summary> 2412 /// </summary>
2220 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2413 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2221 /// <param name="rotation">The direction in which this avatar should now face. 2414 /// <param name="rotation">The direction in which this avatar should now face.
2222 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2415 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2223 { 2416 {
2224 if (m_isChildAgent) 2417 if (m_isChildAgent)
2225 { 2418 {
@@ -2296,7 +2489,7 @@ namespace OpenSim.Region.Framework.Scenes
2296 2489
2297 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2490 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2298 m_forceToApply = direc; 2491 m_forceToApply = direc;
2299 2492 m_isNudging = Nudging;
2300 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2493 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2301 } 2494 }
2302 2495
@@ -2311,7 +2504,7 @@ namespace OpenSim.Region.Framework.Scenes
2311 const float POSITION_TOLERANCE = 0.05f; 2504 const float POSITION_TOLERANCE = 0.05f;
2312 //const int TIME_MS_TOLERANCE = 3000; 2505 //const int TIME_MS_TOLERANCE = 3000;
2313 2506
2314 SendPrimUpdates(); 2507
2315 2508
2316 if (m_newCoarseLocations) 2509 if (m_newCoarseLocations)
2317 { 2510 {
@@ -2347,6 +2540,9 @@ namespace OpenSim.Region.Framework.Scenes
2347 CheckForBorderCrossing(); 2540 CheckForBorderCrossing();
2348 CheckForSignificantMovement(); // sends update to the modules. 2541 CheckForSignificantMovement(); // sends update to the modules.
2349 } 2542 }
2543
2544 //Sending prim updates AFTER the avatar terse updates are sent
2545 SendPrimUpdates();
2350 } 2546 }
2351 2547
2352 #endregion 2548 #endregion
@@ -3251,14 +3447,25 @@ namespace OpenSim.Region.Framework.Scenes
3251 { 3447 {
3252 if (m_forceToApply.HasValue) 3448 if (m_forceToApply.HasValue)
3253 { 3449 {
3254 Vector3 force = m_forceToApply.Value;
3255 3450
3451 Vector3 force = m_forceToApply.Value;
3256 m_updateflag = true; 3452 m_updateflag = true;
3257// movementvector = force;
3258 Velocity = force; 3453 Velocity = force;
3259 3454
3260 m_forceToApply = null; 3455 m_forceToApply = null;
3261 } 3456 }
3457 else
3458 {
3459 if (m_isNudging)
3460 {
3461 Vector3 force = Vector3.Zero;
3462
3463 m_updateflag = true;
3464 Velocity = force;
3465 m_isNudging = false;
3466 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3467 }
3468 }
3262 } 3469 }
3263 3470
3264 public override void SetText(string text, Vector3 color, double alpha) 3471 public override void SetText(string text, Vector3 color, double alpha)
@@ -3309,18 +3516,29 @@ namespace OpenSim.Region.Framework.Scenes
3309 { 3516 {
3310 if (e == null) 3517 if (e == null)
3311 return; 3518 return;
3312 3519
3313 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3520 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3314 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3315 // as of this comment the interval is set in AddToPhysicalScene 3521 // as of this comment the interval is set in AddToPhysicalScene
3316 if (Animator!=null) 3522 if (Animator!=null)
3317 Animator.UpdateMovementAnimations(); 3523 {
3524 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3525 { // else its will lock out other animation changes, like ground sit.
3526 Animator.UpdateMovementAnimations();
3527 m_updateCount--;
3528 }
3529 }
3318 3530
3319 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3531 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3320 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3532 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3321 3533
3322 CollisionPlane = Vector4.UnitW; 3534 CollisionPlane = Vector4.UnitW;
3323 3535
3536 if (m_lastColCount != coldata.Count)
3537 {
3538 m_updateCount = UPDATE_COUNT;
3539 m_lastColCount = coldata.Count;
3540 }
3541
3324 if (coldata.Count != 0 && Animator != null) 3542 if (coldata.Count != 0 && Animator != null)
3325 { 3543 {
3326 switch (Animator.CurrentMovementAnimation) 3544 switch (Animator.CurrentMovementAnimation)
@@ -3927,5 +4145,16 @@ namespace OpenSim.Region.Framework.Scenes
3927 m_reprioritization_called = false; 4145 m_reprioritization_called = false;
3928 } 4146 }
3929 } 4147 }
4148
4149 private Vector3 Quat2Euler(Quaternion rot){
4150 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4151 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4152 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4153 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4154 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4155 return(new Vector3(x,y,z));
4156 }
4157
4158
3930 } 4159 }
3931} 4160}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index c6cf4cc..4ba4fab 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes
75 75
76 foreach (EntityBase e in m_presence.Scene.Entities) 76 foreach (EntityBase e in m_presence.Scene.Entities)
77 { 77 {
78 if (e is SceneObjectGroup) 78 if (e != null && e is SceneObjectGroup)
79 m_pendingObjects.Enqueue((SceneObjectGroup)e); 79 m_pendingObjects.Enqueue((SceneObjectGroup)e);
80 } 80 }
81 } 81 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index c77220c..68035ca 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;