aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs29
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs47
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs519
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs101
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs380
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs577
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
15 files changed, 1267 insertions, 627 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
index 78bd622..7312799 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
103 103
104 void StoreRegionSettings(RegionSettings rs); 104 void StoreRegionSettings(RegionSettings rs);
105 RegionSettings LoadRegionSettings(UUID regionUUID); 105 RegionSettings LoadRegionSettings(UUID regionUUID);
106 RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
107 void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
106 108
107 void Shutdown(); 109 void Shutdown();
108 } 110 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index fd526eb..e98f0e7 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
53 { 53 {
54 get { return m_movementAnimation; } 54 get { return m_movementAnimation; }
55 } 55 }
56 protected string m_movementAnimation = "DEFAULT"; 56 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
57 57 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
58 private int m_animTickFall; 58 private int m_animTickFall;
59 private int m_animTickJump; 59 private int m_animTickJump;
60 60
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
123 /// </summary> 123 /// </summary>
124 public void TrySetMovementAnimation(string anim) 124 public void TrySetMovementAnimation(string anim)
125 { 125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim); 126//Console.WriteLine("Updating movement animation to {0}", anim);
127 127
128 if (!m_scenePresence.IsChildAgent) 128 if (!m_scenePresence.IsChildAgent)
129 { 129 {
130 if (m_animations.TrySetDefaultAnimation( 130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
132 { 132 {
133//Console.WriteLine("TSMA {0} success.", anim);
133 // 16384 is CHANGED_ANIMATION 134 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); 135 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack(); 136 SendAnimPack();
136 } 137 }
138 else
139 {
140//Console.WriteLine("TSMA {0} fail.", anim);
141 }
137 } 142 }
138 } 143 }
139 144
@@ -146,10 +151,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
146 const float PREJUMP_DELAY = 0.25f; 151 const float PREJUMP_DELAY = 0.25f;
147 152
148 #region Inputs 153 #region Inputs
149 if (m_scenePresence.SitGround) 154
150 {
151 return "SIT_GROUND_CONSTRAINED";
152 }
153 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; 155 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
154 PhysicsActor actor = m_scenePresence.PhysicsActor; 156 PhysicsActor actor = m_scenePresence.PhysicsActor;
155 157
@@ -159,11 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
159 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
160 162
161 // Check control flags 163 // Check control flags
162 bool heldForward = 164 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
163 (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); 165 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
164 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 166 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
165 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 167 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
166 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
167 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 168 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
168 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 169 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
169 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 170 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -316,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
316 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
317 { 318 {
318 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
319 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
320 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
321 { 322 {
322 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -454,4 +455,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
454 m_scenePresence = null; 455 m_scenePresence = null;
455 } 456 }
456 } 457 }
457} \ No newline at end of file 458}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 464ead8..139fda0 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 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 215 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
212 216
@@ -428,6 +432,8 @@ namespace OpenSim.Region.Framework.Scenes
428 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 432 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
429 private ClientClosed handlerClientClosed = null; //OnClientClosed; 433 private ClientClosed handlerClientClosed = null; //OnClientClosed;
430 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 434 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
435 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
436 private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted;
431 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 437 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
432 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 438 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
433 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 439 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -801,6 +807,24 @@ namespace OpenSim.Region.Framework.Scenes
801 } 807 }
802 } 808 }
803 809
810 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
811 {
812 handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
813 if (handlerSendNewWindlightProfileTargeted != null)
814 {
815 handlerSendNewWindlightProfileTargeted(wl, user);
816 }
817 }
818
819 public void TriggerOnSaveNewWindlightProfile()
820 {
821 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
822 if (handlerSaveNewWindlightProfile != null)
823 {
824 handlerSaveNewWindlightProfile();
825 }
826 }
827
804 public void TriggerOnMakeRootAgent(ScenePresence presence) 828 public void TriggerOnMakeRootAgent(ScenePresence presence)
805 { 829 {
806 handlerMakeRootAgent = OnMakeRootAgent; 830 handlerMakeRootAgent = OnMakeRootAgent;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 7df3e50..7b852a2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -846,8 +846,12 @@ namespace OpenSim.Region.Framework.Scenes
846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 846 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
847 { 847 {
848 SceneObjectPart part = GetSceneObjectPart(localID); 848 SceneObjectPart part = GetSceneObjectPart(localID);
849 SceneObjectGroup group = part.ParentGroup; 849 SceneObjectGroup group = null;
850 if (group != null) 850 if (part != null)
851 {
852 group = part.ParentGroup;
853 }
854 if (part != null && group != null)
851 { 855 {
852 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 856 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
853 if (item == null) 857 if (item == null)
@@ -1801,8 +1805,13 @@ namespace OpenSim.Region.Framework.Scenes
1801 } 1805 }
1802 else 1806 else
1803 { 1807 {
1804 item.BasePermissions = objectGroup.GetEffectivePermissions(); 1808 uint ownerPerms = objectGroup.GetEffectivePermissions();
1805 item.CurrentPermissions = objectGroup.GetEffectivePermissions(); 1809 if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0)
1810 ownerPerms |= (uint)PermissionMask.Modify;
1811
1812 item.BasePermissions = ownerPerms;
1813 item.CurrentPermissions = ownerPerms;
1814
1806 item.NextPermissions = objectGroup.RootPart.NextOwnerMask; 1815 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1807 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; 1816 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1808 item.GroupPermissions = objectGroup.RootPart.GroupMask; 1817 item.GroupPermissions = objectGroup.RootPart.GroupMask;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 73b0b3e..d2f33b0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -539,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes
539 539
540 // Load region settings 540 // Load region settings
541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
542 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
543
542 if (m_storageManager.EstateDataStore != null) 544 if (m_storageManager.EstateDataStore != null)
543 { 545 {
544 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); 546 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
@@ -886,6 +888,15 @@ namespace OpenSim.Region.Framework.Scenes
886 /// <param name="seconds">float indicating duration before restart.</param> 888 /// <param name="seconds">float indicating duration before restart.</param>
887 public virtual void Restart(float seconds) 889 public virtual void Restart(float seconds)
888 { 890 {
891 Restart(seconds, true);
892 }
893
894 /// <summary>
895 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
896 /// </summary>
897 /// <param name="seconds">float indicating duration before restart.</param>
898 public virtual void Restart(float seconds, bool showDialog)
899 {
889 // notifications are done in 15 second increments 900 // notifications are done in 15 second increments
890 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 901 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
891 // It's a 'Cancel restart' request. 902 // It's a 'Cancel restart' request.
@@ -906,8 +917,11 @@ namespace OpenSim.Region.Framework.Scenes
906 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 917 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
907 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 918 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
908 m_restartTimer.Start(); 919 m_restartTimer.Start();
909 m_dialogModule.SendNotificationToUsersInRegion( 920 if (showDialog)
921 {
922 m_dialogModule.SendNotificationToUsersInRegion(
910 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0))); 923 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
924 }
911 } 925 }
912 } 926 }
913 927
@@ -1189,16 +1203,16 @@ namespace OpenSim.Region.Framework.Scenes
1189 // Check if any objects have reached their targets 1203 // Check if any objects have reached their targets
1190 CheckAtTargets(); 1204 CheckAtTargets();
1191 1205
1192 // Update SceneObjectGroups that have scheduled themselves for updates
1193 // Objects queue their updates onto all scene presences
1194 if (m_frame % m_update_objects == 0)
1195 m_sceneGraph.UpdateObjectGroups();
1196
1197 // Run through all ScenePresences looking for updates 1206 // Run through all ScenePresences looking for updates
1198 // Presence updates and queued object updates for each presence are sent to clients 1207 // Presence updates and queued object updates for each presence are sent to clients
1199 if (m_frame % m_update_presences == 0) 1208 if (m_frame % m_update_presences == 0)
1200 m_sceneGraph.UpdatePresences(); 1209 m_sceneGraph.UpdatePresences();
1201 1210
1211 // Update SceneObjectGroups that have scheduled themselves for updates
1212 // Objects queue their updates onto all scene presences
1213 if (m_frame % m_update_objects == 0)
1214 m_sceneGraph.UpdateObjectGroups();
1215
1202 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1216 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1203 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1217 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1204 m_sceneGraph.UpdatePreparePhysics(); 1218 m_sceneGraph.UpdatePreparePhysics();
@@ -1509,6 +1523,19 @@ namespace OpenSim.Region.Framework.Scenes
1509 public void SaveTerrain() 1523 public void SaveTerrain()
1510 { 1524 {
1511 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1525 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1526 }
1527
1528 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1529 {
1530 m_regInfo.WindlightSettings = wl;
1531 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1532 m_eventManager.TriggerOnSaveNewWindlightProfile();
1533 }
1534
1535 public void LoadWindlightProfile()
1536 {
1537 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1538 m_eventManager.TriggerOnSaveNewWindlightProfile();
1512 } 1539 }
1513 1540
1514 /// <summary> 1541 /// <summary>
@@ -3396,6 +3423,9 @@ namespace OpenSim.Region.Framework.Scenes
3396 3423
3397 CapsModule.AddCapsHandler(agent.AgentID); 3424 CapsModule.AddCapsHandler(agent.AgentID);
3398 3425
3426 if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
3427 System.Threading.Thread.Sleep(2000);
3428
3399 if (!agent.child) 3429 if (!agent.child)
3400 { 3430 {
3401 if (TestBorderCross(agent.startpos,Cardinals.E)) 3431 if (TestBorderCross(agent.startpos,Cardinals.E))
@@ -3454,6 +3484,7 @@ namespace OpenSim.Region.Framework.Scenes
3454 } 3484 }
3455 } 3485 }
3456 // Honor parcel landing type and position. 3486 // Honor parcel landing type and position.
3487 /*
3457 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3488 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3458 if (land != null) 3489 if (land != null)
3459 { 3490 {
@@ -3462,6 +3493,7 @@ namespace OpenSim.Region.Framework.Scenes
3462 agent.startpos = land.LandData.UserLocation; 3493 agent.startpos = land.LandData.UserLocation;
3463 } 3494 }
3464 } 3495 }
3496 */// This is now handled properly in ScenePresence.MakeRootAgent
3465 } 3497 }
3466 3498
3467 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3499 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 6164368..6a3c386 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -699,17 +699,42 @@ namespace OpenSim.Region.Framework.Scenes
699 { 699 {
700 m_log.DebugFormat( 700 m_log.DebugFormat(
701 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", 701 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
702 position, m_regionInfo.RegionName); 702 position, m_regionInfo.RegionName);
703 703
704 // Teleport within the same region 704 // Teleport within the same region
705 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) 705 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
706 { 706 {
707 Vector3 emergencyPos = new Vector3(128, 128, 128); 707 Vector3 emergencyPos = new Vector3(128, 128, 128);
708 708
709 m_log.WarnFormat( 709 m_log.WarnFormat(
710 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 710 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
711 position, avatar.Name, avatar.UUID, emergencyPos); 711 position, avatar.Name, avatar.UUID, emergencyPos);
712 position = emergencyPos; 712 position = emergencyPos;
713 }
714
715 Vector3 currentPos = avatar.AbsolutePosition;
716 ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
717 ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
718 if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
719 {
720 if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
721 {
722 //TPing within the same parcel. If the landing point is restricted, block the TP.
723 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
724 if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
725 {
726 avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
727 position = currentPos;
728 }
729 }
730 else
731 {
732 //Tping to a different parcel. Respect the landing point on the destination parcel.
733 if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
734 {
735 position = destLand.LandData.UserLocation;
736 }
737 }
713 } 738 }
714 739
715 // TODO: Get proper AVG Height 740 // TODO: Get proper AVG Height
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 1ac061a..2c66719 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -222,6 +222,30 @@ namespace OpenSim.Region.Framework.Scenes
222 protected internal bool AddRestoredSceneObject( 222 protected internal bool AddRestoredSceneObject(
223 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) 223 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
224 { 224 {
225 // KF: Check for out-of-region, move inside and make static.
226 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
227 sceneObject.RootPart.GroupPosition.Y,
228 sceneObject.RootPart.GroupPosition.Z);
229 if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
230 npos.X > Constants.RegionSize ||
231 npos.Y > Constants.RegionSize))
232 {
233 if (npos.X < 0.0) npos.X = 1.0f;
234 if (npos.Y < 0.0) npos.Y = 1.0f;
235 if (npos.Z < 0.0) npos.Z = 0.0f;
236 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
237 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
238
239 foreach (SceneObjectPart part in sceneObject.Children.Values)
240 {
241 part.GroupPosition = npos;
242 }
243 sceneObject.RootPart.Velocity = Vector3.Zero;
244 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
245 sceneObject.RootPart.Acceleration = Vector3.Zero;
246 sceneObject.RootPart.Velocity = Vector3.Zero;
247 }
248
225 if (!alreadyPersisted) 249 if (!alreadyPersisted)
226 { 250 {
227 sceneObject.ForceInventoryPersistence(); 251 sceneObject.ForceInventoryPersistence();
@@ -558,6 +582,18 @@ namespace OpenSim.Region.Framework.Scenes
558 if (group.GetFromItemID() == itemID) 582 if (group.GetFromItemID() == itemID)
559 { 583 {
560 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); 584 m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
585 bool hasScripts = false;
586 foreach (SceneObjectPart part in group.Children.Values)
587 {
588 if (part.Inventory.ContainsScripts())
589 {
590 hasScripts = true;
591 break;
592 }
593 }
594
595 if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
596 System.Threading.Thread.Sleep(100);
561 group.DetachToInventoryPrep(); 597 group.DetachToInventoryPrep();
562 m_log.Debug("[DETACH]: Saving attachpoint: " + 598 m_log.Debug("[DETACH]: Saving attachpoint: " +
563 ((uint)group.GetAttachmentPoint()).ToString()); 599 ((uint)group.GetAttachmentPoint()).ToString());
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 71354b4..8b58b3e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -46,12 +46,12 @@ namespace OpenSim.Region.Framework.Scenes
46 /// </summary> 46 /// </summary>
47 public void ForceInventoryPersistence() 47 public void ForceInventoryPersistence()
48 { 48 {
49 lock (m_parts) 49 lockPartsForRead(true);
50 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
51 lockPartsForRead(false);
52 foreach (SceneObjectPart part in values)
50 { 53 {
51 foreach (SceneObjectPart part in m_parts.Values) 54 part.Inventory.ForceInventoryPersistence();
52 {
53 part.Inventory.ForceInventoryPersistence();
54 }
55 } 55 }
56 } 56 }
57 57
@@ -74,19 +74,17 @@ namespace OpenSim.Region.Framework.Scenes
74 /// <summary> 74 /// <summary>
75 /// Stop the scripts contained in all the prims in this group 75 /// Stop the scripts contained in all the prims in this group
76 /// </summary> 76 /// </summary>
77 /// <param name="sceneObjectBeingDeleted">
78 /// Should be true if these scripts are being removed because the scene
79 /// object is being deleted. This will prevent spurious updates to the client.
80 /// </param>
81 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 77 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
82 { 78 {
83 lock (m_parts) 79 lockPartsForRead(true);
80 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
81 lockPartsForRead(false);
82
83 foreach (SceneObjectPart part in values)
84 { 84 {
85 foreach (SceneObjectPart part in m_parts.Values) 85 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
86 {
87 part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
88 }
89 } 86 }
87
90 } 88 }
91 89
92 /// <summary> 90 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index ec41ac7..768ceb5 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 {
@@ -255,13 +321,16 @@ namespace OpenSim.Region.Framework.Scenes
255 set 321 set
256 { 322 {
257 m_regionHandle = value; 323 m_regionHandle = value;
258 lock (m_parts) 324 lockPartsForRead(true);
259 { 325 {
260 foreach (SceneObjectPart part in m_parts.Values) 326 foreach (SceneObjectPart part in m_parts.Values)
261 { 327 {
328
262 part.RegionHandle = m_regionHandle; 329 part.RegionHandle = m_regionHandle;
330
263 } 331 }
264 } 332 }
333 lockPartsForRead(false);
265 } 334 }
266 } 335 }
267 336
@@ -287,13 +356,16 @@ namespace OpenSim.Region.Framework.Scenes
287 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 356 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
288 } 357 }
289 358
290 lock (m_parts) 359 lockPartsForRead(true);
291 { 360 {
292 foreach (SceneObjectPart part in m_parts.Values) 361 foreach (SceneObjectPart part in m_parts.Values)
293 { 362 {
363
294 part.GroupPosition = val; 364 part.GroupPosition = val;
365
295 } 366 }
296 } 367 }
368 lockPartsForRead(false);
297 369
298 //if (m_rootPart.PhysActor != null) 370 //if (m_rootPart.PhysActor != null)
299 //{ 371 //{
@@ -455,13 +527,16 @@ namespace OpenSim.Region.Framework.Scenes
455 527
456 public void SetFromItemID(UUID AssetId) 528 public void SetFromItemID(UUID AssetId)
457 { 529 {
458 lock (m_parts) 530 lockPartsForRead(true);
459 { 531 {
460 foreach (SceneObjectPart part in m_parts.Values) 532 foreach (SceneObjectPart part in m_parts.Values)
461 { 533 {
534
462 part.FromItemID = AssetId; 535 part.FromItemID = AssetId;
536
463 } 537 }
464 } 538 }
539 lockPartsForRead(false);
465 } 540 }
466 541
467 public UUID GetFromItemID() 542 public UUID GetFromItemID()
@@ -528,10 +603,11 @@ namespace OpenSim.Region.Framework.Scenes
528 Vector3 maxScale = Vector3.Zero; 603 Vector3 maxScale = Vector3.Zero;
529 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 604 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
530 605
531 lock (m_parts) 606 lockPartsForRead(true);
532 { 607 {
533 foreach (SceneObjectPart part in m_parts.Values) 608 foreach (SceneObjectPart part in m_parts.Values)
534 { 609 {
610
535 Vector3 partscale = part.Scale; 611 Vector3 partscale = part.Scale;
536 Vector3 partoffset = part.OffsetPosition; 612 Vector3 partoffset = part.OffsetPosition;
537 613
@@ -542,8 +618,11 @@ namespace OpenSim.Region.Framework.Scenes
542 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 618 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
543 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 619 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
544 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 620 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
621
545 } 622 }
546 } 623 }
624 lockPartsForRead(false);
625
547 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 626 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
548 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 627 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
549 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 628 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -559,10 +638,11 @@ namespace OpenSim.Region.Framework.Scenes
559 638
560 EntityIntersection result = new EntityIntersection(); 639 EntityIntersection result = new EntityIntersection();
561 640
562 lock (m_parts) 641 lockPartsForRead(true);
563 { 642 {
564 foreach (SceneObjectPart part in m_parts.Values) 643 foreach (SceneObjectPart part in m_parts.Values)
565 { 644 {
645
566 // Temporary commented to stop compiler warning 646 // Temporary commented to stop compiler warning
567 //Vector3 partPosition = 647 //Vector3 partPosition =
568 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 648 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -590,8 +670,10 @@ namespace OpenSim.Region.Framework.Scenes
590 result.distance = inter.distance; 670 result.distance = inter.distance;
591 } 671 }
592 } 672 }
673
593 } 674 }
594 } 675 }
676 lockPartsForRead(false);
595 return result; 677 return result;
596 } 678 }
597 679
@@ -604,10 +686,11 @@ namespace OpenSim.Region.Framework.Scenes
604 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 686 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
605 { 687 {
606 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 688 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
607 lock (m_parts) 689 lockPartsForRead(true);
608 { 690 {
609 foreach (SceneObjectPart part in m_parts.Values) 691 foreach (SceneObjectPart part in m_parts.Values)
610 { 692 {
693
611 Vector3 worldPos = part.GetWorldPosition(); 694 Vector3 worldPos = part.GetWorldPosition();
612 Vector3 offset = worldPos - AbsolutePosition; 695 Vector3 offset = worldPos - AbsolutePosition;
613 Quaternion worldRot; 696 Quaternion worldRot;
@@ -666,6 +749,8 @@ namespace OpenSim.Region.Framework.Scenes
666 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 749 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
667 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 750 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
668 751
752
753
669 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 754 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
670 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 755 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
671 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 756 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -837,6 +922,7 @@ namespace OpenSim.Region.Framework.Scenes
837 minZ = backBottomLeft.Z; 922 minZ = backBottomLeft.Z;
838 } 923 }
839 } 924 }
925 lockPartsForRead(false);
840 926
841 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 927 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
842 928
@@ -865,17 +951,20 @@ namespace OpenSim.Region.Framework.Scenes
865 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 951 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
866 952
867 // Capture script state while holding the lock 953 // Capture script state while holding the lock
868 lock (m_parts) 954 lockPartsForRead(true);
869 { 955 {
870 foreach (SceneObjectPart part in m_parts.Values) 956 foreach (SceneObjectPart part in m_parts.Values)
871 { 957 {
958
872 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 959 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
873 foreach (UUID itemid in pstates.Keys) 960 foreach (UUID itemid in pstates.Keys)
874 { 961 {
875 states.Add(itemid, pstates[itemid]); 962 states.Add(itemid, pstates[itemid]);
876 } 963 }
964
877 } 965 }
878 } 966 }
967 lockPartsForRead(false);
879 968
880 if (states.Count > 0) 969 if (states.Count > 0)
881 { 970 {
@@ -1037,13 +1126,16 @@ namespace OpenSim.Region.Framework.Scenes
1037 1126
1038 public override void UpdateMovement() 1127 public override void UpdateMovement()
1039 { 1128 {
1040 lock (m_parts) 1129 lockPartsForRead(true);
1041 { 1130 {
1042 foreach (SceneObjectPart part in m_parts.Values) 1131 foreach (SceneObjectPart part in m_parts.Values)
1043 { 1132 {
1133
1044 part.UpdateMovement(); 1134 part.UpdateMovement();
1135
1045 } 1136 }
1046 } 1137 }
1138 lockPartsForRead(false);
1047 } 1139 }
1048 1140
1049 public ushort GetTimeDilation() 1141 public ushort GetTimeDilation()
@@ -1087,7 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes
1087 /// <param name="part"></param> 1179 /// <param name="part"></param>
1088 public void AddPart(SceneObjectPart part) 1180 public void AddPart(SceneObjectPart part)
1089 { 1181 {
1090 lock (m_parts) 1182 lockPartsForWrite(true);
1091 { 1183 {
1092 part.SetParent(this); 1184 part.SetParent(this);
1093 m_parts.Add(part.UUID, part); 1185 m_parts.Add(part.UUID, part);
@@ -1097,6 +1189,7 @@ namespace OpenSim.Region.Framework.Scenes
1097 if (part.LinkNum == 2 && RootPart != null) 1189 if (part.LinkNum == 2 && RootPart != null)
1098 RootPart.LinkNum = 1; 1190 RootPart.LinkNum = 1;
1099 } 1191 }
1192 lockPartsForWrite(false);
1100 } 1193 }
1101 1194
1102 /// <summary> 1195 /// <summary>
@@ -1104,28 +1197,33 @@ namespace OpenSim.Region.Framework.Scenes
1104 /// </summary> 1197 /// </summary>
1105 private void UpdateParentIDs() 1198 private void UpdateParentIDs()
1106 { 1199 {
1107 lock (m_parts) 1200 lockPartsForRead(true);
1108 { 1201 {
1109 foreach (SceneObjectPart part in m_parts.Values) 1202 foreach (SceneObjectPart part in m_parts.Values)
1110 { 1203 {
1204
1111 if (part.UUID != m_rootPart.UUID) 1205 if (part.UUID != m_rootPart.UUID)
1112 { 1206 {
1113 part.ParentID = m_rootPart.LocalId; 1207 part.ParentID = m_rootPart.LocalId;
1114 } 1208 }
1209
1115 } 1210 }
1116 } 1211 }
1212 lockPartsForRead(false);
1117 } 1213 }
1118 1214
1119 public void RegenerateFullIDs() 1215 public void RegenerateFullIDs()
1120 { 1216 {
1121 lock (m_parts) 1217 lockPartsForRead(true);
1122 { 1218 {
1123 foreach (SceneObjectPart part in m_parts.Values) 1219 foreach (SceneObjectPart part in m_parts.Values)
1124 { 1220 {
1221
1125 part.UUID = UUID.Random(); 1222 part.UUID = UUID.Random();
1126 1223
1127 } 1224 }
1128 } 1225 }
1226 lockPartsForRead(false);
1129 } 1227 }
1130 1228
1131 // helper provided for parts. 1229 // helper provided for parts.
@@ -1206,29 +1304,33 @@ namespace OpenSim.Region.Framework.Scenes
1206 1304
1207 DetachFromBackup(); 1305 DetachFromBackup();
1208 1306
1209 lock (m_parts) 1307 lockPartsForRead(true);
1308 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1309 lockPartsForRead(false);
1310
1311 foreach (SceneObjectPart part in values)
1210 { 1312 {
1211 foreach (SceneObjectPart part in m_parts.Values)
1212 {
1213// part.Inventory.RemoveScriptInstances(); 1313// part.Inventory.RemoveScriptInstances();
1214 1314
1215 ScenePresence[] avatars = Scene.GetScenePresences(); 1315 ScenePresence[] avatars = Scene.GetScenePresences();
1216 for (int i = 0; i < avatars.Length; i++) 1316 for (int i = 0; i < avatars.Length; i++)
1317 {
1318 if (avatars[i].ParentID == LocalId)
1217 { 1319 {
1218 if (avatars[i].ParentID == LocalId) 1320 avatars[i].StandUp();
1219 { 1321 }
1220 avatars[i].StandUp();
1221 }
1222 1322
1223 if (!silent) 1323 if (!silent)
1224 { 1324 {
1225 part.UpdateFlag = 0; 1325 part.UpdateFlag = 0;
1226 if (part == m_rootPart) 1326 if (part == m_rootPart)
1227 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1327 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1228 }
1229 } 1328 }
1230 } 1329 }
1330
1231 } 1331 }
1332
1333
1232 } 1334 }
1233 1335
1234 public void AddScriptLPS(int count) 1336 public void AddScriptLPS(int count)
@@ -1253,17 +1355,20 @@ namespace OpenSim.Region.Framework.Scenes
1253 1355
1254 scriptEvents aggregateScriptEvents=0; 1356 scriptEvents aggregateScriptEvents=0;
1255 1357
1256 lock (m_parts) 1358 lockPartsForRead(true);
1257 { 1359 {
1258 foreach (SceneObjectPart part in m_parts.Values) 1360 foreach (SceneObjectPart part in m_parts.Values)
1259 { 1361 {
1362
1260 if (part == null) 1363 if (part == null)
1261 continue; 1364 continue;
1262 if (part != RootPart) 1365 if (part != RootPart)
1263 part.ObjectFlags = objectflagupdate; 1366 part.ObjectFlags = objectflagupdate;
1264 aggregateScriptEvents |= part.AggregateScriptEvents; 1367 aggregateScriptEvents |= part.AggregateScriptEvents;
1368
1265 } 1369 }
1266 } 1370 }
1371 lockPartsForRead(false);
1267 1372
1268 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1373 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1269 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1374 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1305,42 +1410,52 @@ namespace OpenSim.Region.Framework.Scenes
1305 /// <param name="m_physicalPrim"></param> 1410 /// <param name="m_physicalPrim"></param>
1306 public void ApplyPhysics(bool m_physicalPrim) 1411 public void ApplyPhysics(bool m_physicalPrim)
1307 { 1412 {
1308 lock (m_parts) 1413 lockPartsForRead(true);
1414
1415 if (m_parts.Count > 1)
1309 { 1416 {
1310 if (m_parts.Count > 1) 1417 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1418 lockPartsForRead(false);
1419 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1420 foreach (SceneObjectPart part in values)
1311 { 1421 {
1312 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1422
1313 foreach (SceneObjectPart part in m_parts.Values) 1423 if (part.LocalId != m_rootPart.LocalId)
1314 { 1424 {
1315 if (part.LocalId != m_rootPart.LocalId) 1425 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1316 {
1317 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1318 }
1319 } 1426 }
1320 1427
1321 // Hack to get the physics scene geometries in the right spot
1322 ResetChildPrimPhysicsPositions();
1323 }
1324 else
1325 {
1326 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1327 } 1428 }
1429 // Hack to get the physics scene geometries in the right spot
1430 ResetChildPrimPhysicsPositions();
1431 }
1432 else
1433 {
1434 lockPartsForRead(false);
1435 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1328 } 1436 }
1329 } 1437 }
1330 1438
1331 public void SetOwnerId(UUID userId) 1439 public void SetOwnerId(UUID userId)
1332 { 1440 {
1333 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1441 ForEachPart(delegate(SceneObjectPart part)
1442 {
1443
1444 part.OwnerID = userId;
1445
1446 });
1334 } 1447 }
1335 1448
1336 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1449 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1337 { 1450 {
1338 lock (m_parts) 1451 lockPartsForRead(true);
1452 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1453 lockPartsForRead(false);
1454 foreach (SceneObjectPart part in values)
1339 { 1455 {
1340 foreach (SceneObjectPart part in m_parts.Values) 1456
1341 { 1457 whatToDo(part);
1342 whatToDo(part); 1458
1343 }
1344 } 1459 }
1345 } 1460 }
1346 1461
@@ -1439,14 +1554,17 @@ namespace OpenSim.Region.Framework.Scenes
1439 { 1554 {
1440 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1555 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1441 1556
1442 lock (m_parts) 1557 lockPartsForRead(true);
1443 { 1558 {
1444 foreach (SceneObjectPart part in m_parts.Values) 1559 foreach (SceneObjectPart part in m_parts.Values)
1445 { 1560 {
1561
1446 if (part != RootPart) 1562 if (part != RootPart)
1447 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1563 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1564
1448 } 1565 }
1449 } 1566 }
1567 lockPartsForRead(false);
1450 } 1568 }
1451 1569
1452 /// <summary> 1570 /// <summary>
@@ -1541,10 +1659,11 @@ namespace OpenSim.Region.Framework.Scenes
1541 1659
1542 List<SceneObjectPart> partList; 1660 List<SceneObjectPart> partList;
1543 1661
1544 lock (m_parts) 1662 lockPartsForRead(true);
1545 { 1663
1546 partList = new List<SceneObjectPart>(m_parts.Values); 1664 partList = new List<SceneObjectPart>(m_parts.Values);
1547 } 1665
1666 lockPartsForRead(false);
1548 1667
1549 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1668 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1550 { 1669 {
@@ -1793,6 +1912,7 @@ namespace OpenSim.Region.Framework.Scenes
1793 } 1912 }
1794 } 1913 }
1795 } 1914 }
1915
1796 public void stopLookAt() 1916 public void stopLookAt()
1797 { 1917 {
1798 SceneObjectPart rootpart = m_rootPart; 1918 SceneObjectPart rootpart = m_rootPart;
@@ -1867,10 +1987,11 @@ namespace OpenSim.Region.Framework.Scenes
1867 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1987 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1868 newPart.SetParent(this); 1988 newPart.SetParent(this);
1869 1989
1870 lock (m_parts) 1990 lockPartsForWrite(true);
1871 { 1991 {
1872 m_parts.Add(newPart.UUID, newPart); 1992 m_parts.Add(newPart.UUID, newPart);
1873 } 1993 }
1994 lockPartsForWrite(false);
1874 1995
1875 SetPartAsNonRoot(newPart); 1996 SetPartAsNonRoot(newPart);
1876 1997
@@ -1933,7 +2054,7 @@ namespace OpenSim.Region.Framework.Scenes
1933 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2054 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1934 // return; 2055 // return;
1935 2056
1936 lock (m_parts) 2057 lockPartsForRead(true);
1937 { 2058 {
1938 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2059 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1939 2060
@@ -1951,34 +2072,43 @@ namespace OpenSim.Region.Framework.Scenes
1951 2072
1952 foreach (SceneObjectPart part in m_parts.Values) 2073 foreach (SceneObjectPart part in m_parts.Values)
1953 { 2074 {
2075
1954 part.SendScheduledUpdates(); 2076 part.SendScheduledUpdates();
2077
1955 } 2078 }
1956 } 2079 }
2080 lockPartsForRead(false);
1957 } 2081 }
1958 2082
1959 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2083 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1960 { 2084 {
1961 RootPart.AddFullUpdateToAvatar(presence); 2085 RootPart.AddFullUpdateToAvatar(presence);
1962 2086
1963 lock (m_parts) 2087 lockPartsForRead(true);
1964 { 2088 {
1965 foreach (SceneObjectPart part in m_parts.Values) 2089 foreach (SceneObjectPart part in m_parts.Values)
1966 { 2090 {
2091
1967 if (part != RootPart) 2092 if (part != RootPart)
1968 part.AddFullUpdateToAvatar(presence); 2093 part.AddFullUpdateToAvatar(presence);
2094
1969 } 2095 }
1970 } 2096 }
2097 lockPartsForRead(false);
1971 } 2098 }
1972 2099
1973 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2100 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1974 { 2101 {
1975 lock (m_parts) 2102 lockPartsForRead(true);
1976 { 2103 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2104 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2105 {
2106
1979 part.AddTerseUpdateToAvatar(presence); 2107 part.AddTerseUpdateToAvatar(presence);
2108
1980 } 2109 }
1981 } 2110 }
2111 lockPartsForRead(false);
1982 } 2112 }
1983 2113
1984 /// <summary> 2114 /// <summary>
@@ -1989,14 +2119,17 @@ namespace OpenSim.Region.Framework.Scenes
1989 checkAtTargets(); 2119 checkAtTargets();
1990 RootPart.ScheduleFullUpdate(); 2120 RootPart.ScheduleFullUpdate();
1991 2121
1992 lock (m_parts) 2122 lockPartsForRead(true);
1993 { 2123 {
1994 foreach (SceneObjectPart part in m_parts.Values) 2124 foreach (SceneObjectPart part in m_parts.Values)
1995 { 2125 {
2126
1996 if (part != RootPart) 2127 if (part != RootPart)
1997 part.ScheduleFullUpdate(); 2128 part.ScheduleFullUpdate();
2129
1998 } 2130 }
1999 } 2131 }
2132 lockPartsForRead(false);
2000 } 2133 }
2001 2134
2002 /// <summary> 2135 /// <summary>
@@ -2004,13 +2137,16 @@ namespace OpenSim.Region.Framework.Scenes
2004 /// </summary> 2137 /// </summary>
2005 public void ScheduleGroupForTerseUpdate() 2138 public void ScheduleGroupForTerseUpdate()
2006 { 2139 {
2007 lock (m_parts) 2140 lockPartsForRead(true);
2008 { 2141 {
2009 foreach (SceneObjectPart part in m_parts.Values) 2142 foreach (SceneObjectPart part in m_parts.Values)
2010 { 2143 {
2144
2011 part.ScheduleTerseUpdate(); 2145 part.ScheduleTerseUpdate();
2146
2012 } 2147 }
2013 } 2148 }
2149 lockPartsForRead(false);
2014 } 2150 }
2015 2151
2016 /// <summary> 2152 /// <summary>
@@ -2023,14 +2159,17 @@ namespace OpenSim.Region.Framework.Scenes
2023 2159
2024 RootPart.SendFullUpdateToAllClients(); 2160 RootPart.SendFullUpdateToAllClients();
2025 2161
2026 lock (m_parts) 2162 lockPartsForRead(true);
2027 { 2163 {
2028 foreach (SceneObjectPart part in m_parts.Values) 2164 foreach (SceneObjectPart part in m_parts.Values)
2029 { 2165 {
2166
2030 if (part != RootPart) 2167 if (part != RootPart)
2031 part.SendFullUpdateToAllClients(); 2168 part.SendFullUpdateToAllClients();
2169
2032 } 2170 }
2033 } 2171 }
2172 lockPartsForRead(false);
2034 } 2173 }
2035 2174
2036 /// <summary> 2175 /// <summary>
@@ -2061,14 +2200,15 @@ namespace OpenSim.Region.Framework.Scenes
2061 { 2200 {
2062 if (IsDeleted) 2201 if (IsDeleted)
2063 return; 2202 return;
2064 2203
2065 lock (m_parts) 2204 lockPartsForRead(true);
2066 { 2205 {
2067 foreach (SceneObjectPart part in m_parts.Values) 2206 foreach (SceneObjectPart part in m_parts.Values)
2068 { 2207 {
2069 part.SendTerseUpdateToAllClients(); 2208 part.SendTerseUpdateToAllClients();
2070 } 2209 }
2071 } 2210 }
2211 lockPartsForRead(false);
2072 } 2212 }
2073 2213
2074 #endregion 2214 #endregion
@@ -2082,16 +2222,18 @@ namespace OpenSim.Region.Framework.Scenes
2082 /// <returns>null if no child part with that linknum or child part</returns> 2222 /// <returns>null if no child part with that linknum or child part</returns>
2083 public SceneObjectPart GetLinkNumPart(int linknum) 2223 public SceneObjectPart GetLinkNumPart(int linknum)
2084 { 2224 {
2085 lock (m_parts) 2225 lockPartsForRead(true);
2086 { 2226 {
2087 foreach (SceneObjectPart part in m_parts.Values) 2227 foreach (SceneObjectPart part in m_parts.Values)
2088 { 2228 {
2089 if (part.LinkNum == linknum) 2229 if (part.LinkNum == linknum)
2090 { 2230 {
2231 lockPartsForRead(false);
2091 return part; 2232 return part;
2092 } 2233 }
2093 } 2234 }
2094 } 2235 }
2236 lockPartsForRead(false);
2095 2237
2096 return null; 2238 return null;
2097 } 2239 }
@@ -2119,17 +2261,19 @@ namespace OpenSim.Region.Framework.Scenes
2119 public SceneObjectPart GetChildPart(uint localID) 2261 public SceneObjectPart GetChildPart(uint localID)
2120 { 2262 {
2121 //m_log.DebugFormat("Entered looking for {0}", localID); 2263 //m_log.DebugFormat("Entered looking for {0}", localID);
2122 lock (m_parts) 2264 lockPartsForRead(true);
2123 { 2265 {
2124 foreach (SceneObjectPart part in m_parts.Values) 2266 foreach (SceneObjectPart part in m_parts.Values)
2125 { 2267 {
2126 //m_log.DebugFormat("Found {0}", part.LocalId); 2268 //m_log.DebugFormat("Found {0}", part.LocalId);
2127 if (part.LocalId == localID) 2269 if (part.LocalId == localID)
2128 { 2270 {
2271 lockPartsForRead(false);
2129 return part; 2272 return part;
2130 } 2273 }
2131 } 2274 }
2132 } 2275 }
2276 lockPartsForRead(false);
2133 2277
2134 return null; 2278 return null;
2135 } 2279 }
@@ -2159,17 +2303,19 @@ namespace OpenSim.Region.Framework.Scenes
2159 public bool HasChildPrim(uint localID) 2303 public bool HasChildPrim(uint localID)
2160 { 2304 {
2161 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2305 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2162 lock (m_parts) 2306 lockPartsForRead(true);
2163 { 2307 {
2164 foreach (SceneObjectPart part in m_parts.Values) 2308 foreach (SceneObjectPart part in m_parts.Values)
2165 { 2309 {
2166 //m_log.DebugFormat("Found {0}", part.LocalId); 2310 //m_log.DebugFormat("Found {0}", part.LocalId);
2167 if (part.LocalId == localID) 2311 if (part.LocalId == localID)
2168 { 2312 {
2313 lockPartsForRead(false);
2169 return true; 2314 return true;
2170 } 2315 }
2171 } 2316 }
2172 } 2317 }
2318 lockPartsForRead(false);
2173 2319
2174 return false; 2320 return false;
2175 } 2321 }
@@ -2219,53 +2365,57 @@ namespace OpenSim.Region.Framework.Scenes
2219 if (m_rootPart.LinkNum == 0) 2365 if (m_rootPart.LinkNum == 0)
2220 m_rootPart.LinkNum = 1; 2366 m_rootPart.LinkNum = 1;
2221 2367
2222 lock (m_parts) 2368 lockPartsForWrite(true);
2223 { 2369
2224 m_parts.Add(linkPart.UUID, linkPart); 2370 m_parts.Add(linkPart.UUID, linkPart);
2225 2371
2226 // Insert in terms of link numbers, the new links 2372 lockPartsForWrite(false);
2227 // before the current ones (with the exception of 2373
2228 // the root prim. Shuffle the old ones up 2374 // Insert in terms of link numbers, the new links
2229 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2375 // before the current ones (with the exception of
2376 // the root prim. Shuffle the old ones up
2377 lockPartsForRead(true);
2378 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2379 {
2380 if (kvp.Value.LinkNum != 1)
2230 { 2381 {
2231 if (kvp.Value.LinkNum != 1) 2382 // Don't update root prim link number
2232 { 2383 kvp.Value.LinkNum += objectGroup.PrimCount;
2233 // Don't update root prim link number
2234 kvp.Value.LinkNum += objectGroup.PrimCount;
2235 }
2236 } 2384 }
2385 }
2386 lockPartsForRead(false);
2237 2387
2238 linkPart.LinkNum = 2; 2388 linkPart.LinkNum = 2;
2239 2389
2240 linkPart.SetParent(this); 2390 linkPart.SetParent(this);
2241 linkPart.AddFlag(PrimFlags.CreateSelected); 2391 linkPart.AddFlag(PrimFlags.CreateSelected);
2242 2392
2243 //if (linkPart.PhysActor != null) 2393 //if (linkPart.PhysActor != null)
2244 //{ 2394 //{
2245 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2395 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2246 2396
2247 //linkPart.PhysActor = null; 2397 //linkPart.PhysActor = null;
2248 //} 2398 //}
2249 2399
2250 //TODO: rest of parts 2400 //TODO: rest of parts
2251 int linkNum = 3; 2401 int linkNum = 3;
2252 foreach (SceneObjectPart part in objectGroup.Children.Values) 2402 foreach (SceneObjectPart part in objectGroup.Children.Values)
2403 {
2404 if (part.UUID != objectGroup.m_rootPart.UUID)
2253 { 2405 {
2254 if (part.UUID != objectGroup.m_rootPart.UUID) 2406 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2255 {
2256 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2257 }
2258 part.ClearUndoState();
2259 } 2407 }
2408 part.ClearUndoState();
2260 } 2409 }
2261 2410
2262 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2411 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2263 objectGroup.m_isDeleted = true; 2412 objectGroup.m_isDeleted = true;
2413
2414 objectGroup.lockPartsForWrite(true);
2264 2415
2265 lock (objectGroup.m_parts) 2416 objectGroup.m_parts.Clear();
2266 { 2417
2267 objectGroup.m_parts.Clear(); 2418 objectGroup.lockPartsForWrite(false);
2268 }
2269 2419
2270 // Can't do this yet since backup still makes use of the root part without any synchronization 2420 // Can't do this yet since backup still makes use of the root part without any synchronization
2271// objectGroup.m_rootPart = null; 2421// objectGroup.m_rootPart = null;
@@ -2324,11 +2474,12 @@ namespace OpenSim.Region.Framework.Scenes
2324 Quaternion worldRot = linkPart.GetWorldRotation(); 2474 Quaternion worldRot = linkPart.GetWorldRotation();
2325 2475
2326 // Remove the part from this object 2476 // Remove the part from this object
2327 lock (m_parts) 2477 lockPartsForWrite(true);
2328 { 2478 {
2329 m_parts.Remove(linkPart.UUID); 2479 m_parts.Remove(linkPart.UUID);
2330 } 2480 }
2331 2481 lockPartsForWrite(false);
2482 lockPartsForRead(true);
2332 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2483 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2333 RootPart.LinkNum = 0; 2484 RootPart.LinkNum = 0;
2334 else 2485 else
@@ -2339,6 +2490,7 @@ namespace OpenSim.Region.Framework.Scenes
2339 p.LinkNum--; 2490 p.LinkNum--;
2340 } 2491 }
2341 } 2492 }
2493 lockPartsForRead(false);
2342 2494
2343 linkPart.ParentID = 0; 2495 linkPart.ParentID = 0;
2344 linkPart.LinkNum = 0; 2496 linkPart.LinkNum = 0;
@@ -2656,9 +2808,12 @@ namespace OpenSim.Region.Framework.Scenes
2656 2808
2657 if (selectionPart != null) 2809 if (selectionPart != null)
2658 { 2810 {
2659 lock (m_parts) 2811 lockPartsForRead(true);
2812 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2813 lockPartsForRead(false);
2814 foreach (SceneObjectPart part in parts)
2660 { 2815 {
2661 foreach (SceneObjectPart part in m_parts.Values) 2816 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2662 { 2817 {
2663 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2818 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2664 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2819 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2668,12 +2823,13 @@ namespace OpenSim.Region.Framework.Scenes
2668 break; 2823 break;
2669 } 2824 }
2670 } 2825 }
2826 }
2671 2827
2672 foreach (SceneObjectPart part in m_parts.Values) 2828 foreach (SceneObjectPart part in parts)
2673 { 2829 {
2674 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2830 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2675 }
2676 } 2831 }
2832
2677 } 2833 }
2678 } 2834 }
2679 2835
@@ -2759,11 +2915,9 @@ namespace OpenSim.Region.Framework.Scenes
2759 scale.Y = m_scene.m_maxNonphys; 2915 scale.Y = m_scene.m_maxNonphys;
2760 if (scale.Z > m_scene.m_maxNonphys) 2916 if (scale.Z > m_scene.m_maxNonphys)
2761 scale.Z = m_scene.m_maxNonphys; 2917 scale.Z = m_scene.m_maxNonphys;
2762
2763 SceneObjectPart part = GetChildPart(localID); 2918 SceneObjectPart part = GetChildPart(localID);
2764 if (part != null) 2919 if (part != null)
2765 { 2920 {
2766 part.Resize(scale);
2767 if (part.PhysActor != null) 2921 if (part.PhysActor != null)
2768 { 2922 {
2769 if (part.PhysActor.IsPhysical) 2923 if (part.PhysActor.IsPhysical)
@@ -2778,7 +2932,7 @@ namespace OpenSim.Region.Framework.Scenes
2778 part.PhysActor.Size = scale; 2932 part.PhysActor.Size = scale;
2779 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2933 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2780 } 2934 }
2781 //if (part.UUID != m_rootPart.UUID) 2935 part.Resize(scale);
2782 2936
2783 HasGroupChanged = true; 2937 HasGroupChanged = true;
2784 ScheduleGroupForFullUpdate(); 2938 ScheduleGroupForFullUpdate();
@@ -2819,77 +2973,76 @@ namespace OpenSim.Region.Framework.Scenes
2819 float y = (scale.Y / part.Scale.Y); 2973 float y = (scale.Y / part.Scale.Y);
2820 float z = (scale.Z / part.Scale.Z); 2974 float z = (scale.Z / part.Scale.Z);
2821 2975
2822 lock (m_parts) 2976 lockPartsForRead(true);
2977 if (x > 1.0f || y > 1.0f || z > 1.0f)
2823 { 2978 {
2824 if (x > 1.0f || y > 1.0f || z > 1.0f) 2979 foreach (SceneObjectPart obPart in m_parts.Values)
2825 { 2980 {
2826 foreach (SceneObjectPart obPart in m_parts.Values) 2981 if (obPart.UUID != m_rootPart.UUID)
2827 { 2982 {
2828 if (obPart.UUID != m_rootPart.UUID) 2983 Vector3 oldSize = new Vector3(obPart.Scale);
2829 {
2830 Vector3 oldSize = new Vector3(obPart.Scale);
2831 2984
2832 float f = 1.0f; 2985 float f = 1.0f;
2833 float a = 1.0f; 2986 float a = 1.0f;
2834 2987
2835 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2988 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2989 {
2990 if (oldSize.X*x > m_scene.m_maxPhys)
2836 { 2991 {
2837 if (oldSize.X*x > m_scene.m_maxPhys) 2992 f = m_scene.m_maxPhys / oldSize.X;
2838 { 2993 a = f / x;
2839 f = m_scene.m_maxPhys / oldSize.X; 2994 x *= a;
2840 a = f / x; 2995 y *= a;
2841 x *= a; 2996 z *= a;
2842 y *= a;
2843 z *= a;
2844 }
2845 if (oldSize.Y*y > m_scene.m_maxPhys)
2846 {
2847 f = m_scene.m_maxPhys / oldSize.Y;
2848 a = f / y;
2849 x *= a;
2850 y *= a;
2851 z *= a;
2852 }
2853 if (oldSize.Z*z > m_scene.m_maxPhys)
2854 {
2855 f = m_scene.m_maxPhys / oldSize.Z;
2856 a = f / z;
2857 x *= a;
2858 y *= a;
2859 z *= a;
2860 }
2861 } 2997 }
2862 else 2998 if (oldSize.Y*y > m_scene.m_maxPhys)
2999 {
3000 f = m_scene.m_maxPhys / oldSize.Y;
3001 a = f / y;
3002 x *= a;
3003 y *= a;
3004 z *= a;
3005 }
3006 if (oldSize.Z*z > m_scene.m_maxPhys)
3007 {
3008 f = m_scene.m_maxPhys / oldSize.Z;
3009 a = f / z;
3010 x *= a;
3011 y *= a;
3012 z *= a;
3013 }
3014 }
3015 else
3016 {
3017 if (oldSize.X*x > m_scene.m_maxNonphys)
3018 {
3019 f = m_scene.m_maxNonphys / oldSize.X;
3020 a = f / x;
3021 x *= a;
3022 y *= a;
3023 z *= a;
3024 }
3025 if (oldSize.Y*y > m_scene.m_maxNonphys)
3026 {
3027 f = m_scene.m_maxNonphys / oldSize.Y;
3028 a = f / y;
3029 x *= a;
3030 y *= a;
3031 z *= a;
3032 }
3033 if (oldSize.Z*z > m_scene.m_maxNonphys)
2863 { 3034 {
2864 if (oldSize.X*x > m_scene.m_maxNonphys) 3035 f = m_scene.m_maxNonphys / oldSize.Z;
2865 { 3036 a = f / z;
2866 f = m_scene.m_maxNonphys / oldSize.X; 3037 x *= a;
2867 a = f / x; 3038 y *= a;
2868 x *= a; 3039 z *= a;
2869 y *= a;
2870 z *= a;
2871 }
2872 if (oldSize.Y*y > m_scene.m_maxNonphys)
2873 {
2874 f = m_scene.m_maxNonphys / oldSize.Y;
2875 a = f / y;
2876 x *= a;
2877 y *= a;
2878 z *= a;
2879 }
2880 if (oldSize.Z*z > m_scene.m_maxNonphys)
2881 {
2882 f = m_scene.m_maxNonphys / oldSize.Z;
2883 a = f / z;
2884 x *= a;
2885 y *= a;
2886 z *= a;
2887 }
2888 } 3040 }
2889 } 3041 }
2890 } 3042 }
2891 } 3043 }
2892 } 3044 }
3045 lockPartsForRead(false);
2893 3046
2894 Vector3 prevScale = part.Scale; 3047 Vector3 prevScale = part.Scale;
2895 prevScale.X *= x; 3048 prevScale.X *= x;
@@ -2897,7 +3050,7 @@ namespace OpenSim.Region.Framework.Scenes
2897 prevScale.Z *= z; 3050 prevScale.Z *= z;
2898 part.Resize(prevScale); 3051 part.Resize(prevScale);
2899 3052
2900 lock (m_parts) 3053 lockPartsForRead(true);
2901 { 3054 {
2902 foreach (SceneObjectPart obPart in m_parts.Values) 3055 foreach (SceneObjectPart obPart in m_parts.Values)
2903 { 3056 {
@@ -2916,6 +3069,7 @@ namespace OpenSim.Region.Framework.Scenes
2916 } 3069 }
2917 } 3070 }
2918 } 3071 }
3072 lockPartsForRead(false);
2919 3073
2920 if (part.PhysActor != null) 3074 if (part.PhysActor != null)
2921 { 3075 {
@@ -2996,7 +3150,7 @@ namespace OpenSim.Region.Framework.Scenes
2996 axDiff *= Quaternion.Inverse(partRotation); 3150 axDiff *= Quaternion.Inverse(partRotation);
2997 diff = axDiff; 3151 diff = axDiff;
2998 3152
2999 lock (m_parts) 3153 lockPartsForRead(true);
3000 { 3154 {
3001 foreach (SceneObjectPart obPart in m_parts.Values) 3155 foreach (SceneObjectPart obPart in m_parts.Values)
3002 { 3156 {
@@ -3006,6 +3160,7 @@ namespace OpenSim.Region.Framework.Scenes
3006 } 3160 }
3007 } 3161 }
3008 } 3162 }
3163 lockPartsForRead(false);
3009 3164
3010 AbsolutePosition = newPos; 3165 AbsolutePosition = newPos;
3011 3166
@@ -3123,7 +3278,7 @@ namespace OpenSim.Region.Framework.Scenes
3123 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3278 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3124 } 3279 }
3125 3280
3126 lock (m_parts) 3281 lockPartsForRead(true);
3127 { 3282 {
3128 foreach (SceneObjectPart prim in m_parts.Values) 3283 foreach (SceneObjectPart prim in m_parts.Values)
3129 { 3284 {
@@ -3141,6 +3296,7 @@ namespace OpenSim.Region.Framework.Scenes
3141 } 3296 }
3142 } 3297 }
3143 } 3298 }
3299 lockPartsForRead(false);
3144 3300
3145 m_rootPart.ScheduleTerseUpdate(); 3301 m_rootPart.ScheduleTerseUpdate();
3146 } 3302 }
@@ -3263,7 +3419,7 @@ namespace OpenSim.Region.Framework.Scenes
3263 if (atTargets.Count > 0) 3419 if (atTargets.Count > 0)
3264 { 3420 {
3265 uint[] localids = new uint[0]; 3421 uint[] localids = new uint[0];
3266 lock (m_parts) 3422 lockPartsForRead(true);
3267 { 3423 {
3268 localids = new uint[m_parts.Count]; 3424 localids = new uint[m_parts.Count];
3269 int cntr = 0; 3425 int cntr = 0;
@@ -3273,6 +3429,7 @@ namespace OpenSim.Region.Framework.Scenes
3273 cntr++; 3429 cntr++;
3274 } 3430 }
3275 } 3431 }
3432 lockPartsForRead(false);
3276 3433
3277 for (int ctr = 0; ctr < localids.Length; ctr++) 3434 for (int ctr = 0; ctr < localids.Length; ctr++)
3278 { 3435 {
@@ -3291,7 +3448,7 @@ namespace OpenSim.Region.Framework.Scenes
3291 { 3448 {
3292 //trigger not_at_target 3449 //trigger not_at_target
3293 uint[] localids = new uint[0]; 3450 uint[] localids = new uint[0];
3294 lock (m_parts) 3451 lockPartsForRead(true);
3295 { 3452 {
3296 localids = new uint[m_parts.Count]; 3453 localids = new uint[m_parts.Count];
3297 int cntr = 0; 3454 int cntr = 0;
@@ -3301,7 +3458,8 @@ namespace OpenSim.Region.Framework.Scenes
3301 cntr++; 3458 cntr++;
3302 } 3459 }
3303 } 3460 }
3304 3461 lockPartsForRead(false);
3462
3305 for (int ctr = 0; ctr < localids.Length; ctr++) 3463 for (int ctr = 0; ctr < localids.Length; ctr++)
3306 { 3464 {
3307 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3465 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3393,19 +3551,20 @@ namespace OpenSim.Region.Framework.Scenes
3393 public float GetMass() 3551 public float GetMass()
3394 { 3552 {
3395 float retmass = 0f; 3553 float retmass = 0f;
3396 lock (m_parts) 3554 lockPartsForRead(true);
3397 { 3555 {
3398 foreach (SceneObjectPart part in m_parts.Values) 3556 foreach (SceneObjectPart part in m_parts.Values)
3399 { 3557 {
3400 retmass += part.GetMass(); 3558 retmass += part.GetMass();
3401 } 3559 }
3402 } 3560 }
3561 lockPartsForRead(false);
3403 return retmass; 3562 return retmass;
3404 } 3563 }
3405 3564
3406 public void CheckSculptAndLoad() 3565 public void CheckSculptAndLoad()
3407 { 3566 {
3408 lock (m_parts) 3567 lockPartsForRead(true);
3409 { 3568 {
3410 if (!IsDeleted) 3569 if (!IsDeleted)
3411 { 3570 {
@@ -3430,6 +3589,7 @@ namespace OpenSim.Region.Framework.Scenes
3430 } 3589 }
3431 } 3590 }
3432 } 3591 }
3592 lockPartsForRead(false);
3433 } 3593 }
3434 3594
3435 protected void AssetReceived(string id, Object sender, AssetBase asset) 3595 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3450,7 +3610,7 @@ namespace OpenSim.Region.Framework.Scenes
3450 /// <param name="client"></param> 3610 /// <param name="client"></param>
3451 public void SetGroup(UUID GroupID, IClientAPI client) 3611 public void SetGroup(UUID GroupID, IClientAPI client)
3452 { 3612 {
3453 lock (m_parts) 3613 lockPartsForRead(true);
3454 { 3614 {
3455 foreach (SceneObjectPart part in m_parts.Values) 3615 foreach (SceneObjectPart part in m_parts.Values)
3456 { 3616 {
@@ -3460,7 +3620,7 @@ namespace OpenSim.Region.Framework.Scenes
3460 3620
3461 HasGroupChanged = true; 3621 HasGroupChanged = true;
3462 } 3622 }
3463 3623 lockPartsForRead(false);
3464 ScheduleGroupForFullUpdate(); 3624 ScheduleGroupForFullUpdate();
3465 } 3625 }
3466 3626
@@ -3479,11 +3639,12 @@ namespace OpenSim.Region.Framework.Scenes
3479 3639
3480 public void SetAttachmentPoint(byte point) 3640 public void SetAttachmentPoint(byte point)
3481 { 3641 {
3482 lock (m_parts) 3642 lockPartsForRead(true);
3483 { 3643 {
3484 foreach (SceneObjectPart part in m_parts.Values) 3644 foreach (SceneObjectPart part in m_parts.Values)
3485 part.SetAttachmentPoint(point); 3645 part.SetAttachmentPoint(point);
3486 } 3646 }
3647 lockPartsForRead(false);
3487 } 3648 }
3488 3649
3489 #region ISceneObject 3650 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ef9005f..a99e6c7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.Framework.Scenes
126 126
127 // TODO: This needs to be persisted in next XML version update! 127 // TODO: This needs to be persisted in next XML version update!
128 [XmlIgnore] 128 [XmlIgnore]
129 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 129 public int[] PayPrice = {-2,-2,-2,-2,-2};
130 [XmlIgnore] 130 [XmlIgnore]
131 public PhysicsActor PhysActor; 131 public PhysicsActor PhysActor;
132 132
@@ -241,6 +241,7 @@ namespace OpenSim.Region.Framework.Scenes
241 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 241 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
242 private Vector3 m_sitTargetPosition; 242 private Vector3 m_sitTargetPosition;
243 private string m_sitAnimation = "SIT"; 243 private string m_sitAnimation = "SIT";
244 private bool m_occupied; // KF if any av is sitting on this prim
244 private string m_text = String.Empty; 245 private string m_text = String.Empty;
245 private string m_touchName = String.Empty; 246 private string m_touchName = String.Empty;
246 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 247 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -418,12 +419,16 @@ namespace OpenSim.Region.Framework.Scenes
418 } 419 }
419 420
420 /// <value> 421 /// <value>
421 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 422 /// Get the inventory list
422 /// </value> 423 /// </value>
423 public TaskInventoryDictionary TaskInventory 424 public TaskInventoryDictionary TaskInventory
424 { 425 {
425 get { return m_inventory.Items; } 426 get {
426 set { m_inventory.Items = value; } 427 return m_inventory.Items;
428 }
429 set {
430 m_inventory.Items = value;
431 }
427 } 432 }
428 433
429 public uint ObjectFlags 434 public uint ObjectFlags
@@ -567,7 +572,6 @@ namespace OpenSim.Region.Framework.Scenes
567 StoreUndoState(); 572 StoreUndoState();
568 573
569 m_groupPosition = value; 574 m_groupPosition = value;
570
571 PhysicsActor actor = PhysActor; 575 PhysicsActor actor = PhysActor;
572 if (actor != null) 576 if (actor != null)
573 { 577 {
@@ -880,7 +884,8 @@ namespace OpenSim.Region.Framework.Scenes
880 if (IsAttachment) 884 if (IsAttachment)
881 return GroupPosition; 885 return GroupPosition;
882 886
883 return m_offsetPosition + m_groupPosition; } 887// return m_offsetPosition + m_groupPosition; }
888 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
884 } 889 }
885 890
886 public SceneObjectGroup ParentGroup 891 public SceneObjectGroup ParentGroup
@@ -1032,6 +1037,13 @@ namespace OpenSim.Region.Framework.Scenes
1032 get { return _flags; } 1037 get { return _flags; }
1033 set { _flags = value; } 1038 set { _flags = value; }
1034 } 1039 }
1040
1041 [XmlIgnore]
1042 public bool IsOccupied // KF If an av is sittingon this prim
1043 {
1044 get { return m_occupied; }
1045 set { m_occupied = value; }
1046 }
1035 1047
1036 [XmlIgnore] 1048 [XmlIgnore]
1037 public UUID SitTargetAvatar 1049 public UUID SitTargetAvatar
@@ -1107,14 +1119,6 @@ namespace OpenSim.Region.Framework.Scenes
1107 } 1119 }
1108 } 1120 }
1109 1121
1110 /// <summary>
1111 /// Clear all pending updates of parts to clients
1112 /// </summary>
1113 private void ClearUpdateSchedule()
1114 {
1115 m_updateFlag = 0;
1116 }
1117
1118 private void SendObjectPropertiesToClient(UUID AgentID) 1122 private void SendObjectPropertiesToClient(UUID AgentID)
1119 { 1123 {
1120 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1124 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1793,12 +1797,17 @@ namespace OpenSim.Region.Framework.Scenes
1793 public Vector3 GetWorldPosition() 1797 public Vector3 GetWorldPosition()
1794 { 1798 {
1795 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1799 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1796
1797 Vector3 axPos = OffsetPosition; 1800 Vector3 axPos = OffsetPosition;
1798
1799 axPos *= parentRot; 1801 axPos *= parentRot;
1800 Vector3 translationOffsetPosition = axPos; 1802 Vector3 translationOffsetPosition = axPos;
1801 return GroupPosition + translationOffsetPosition; 1803 if(_parentID == 0)
1804 {
1805 return GroupPosition;
1806 }
1807 else
1808 {
1809 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1810 }
1802 } 1811 }
1803 1812
1804 /// <summary> 1813 /// <summary>
@@ -1809,7 +1818,7 @@ namespace OpenSim.Region.Framework.Scenes
1809 { 1818 {
1810 Quaternion newRot; 1819 Quaternion newRot;
1811 1820
1812 if (this.LinkNum == 0) 1821 if (this.LinkNum < 2) //KF Single or root prim
1813 { 1822 {
1814 newRot = RotationOffset; 1823 newRot = RotationOffset;
1815 } 1824 }
@@ -2466,17 +2475,18 @@ namespace OpenSim.Region.Framework.Scenes
2466 //Trys to fetch sound id from prim's inventory. 2475 //Trys to fetch sound id from prim's inventory.
2467 //Prim's inventory doesn't support non script items yet 2476 //Prim's inventory doesn't support non script items yet
2468 2477
2469 lock (TaskInventory) 2478 TaskInventory.LockItemsForRead(true);
2479
2480 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2470 { 2481 {
2471 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2482 if (item.Value.Name == sound)
2472 { 2483 {
2473 if (item.Value.Name == sound) 2484 soundID = item.Value.ItemID;
2474 { 2485 break;
2475 soundID = item.Value.ItemID;
2476 break;
2477 }
2478 } 2486 }
2479 } 2487 }
2488
2489 TaskInventory.LockItemsForRead(false);
2480 } 2490 }
2481 2491
2482 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2492 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2753,8 +2763,8 @@ namespace OpenSim.Region.Framework.Scenes
2753 { 2763 {
2754 const float ROTATION_TOLERANCE = 0.01f; 2764 const float ROTATION_TOLERANCE = 0.01f;
2755 const float VELOCITY_TOLERANCE = 0.001f; 2765 const float VELOCITY_TOLERANCE = 0.001f;
2756 const float POSITION_TOLERANCE = 0.05f; 2766 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2757 const int TIME_MS_TOLERANCE = 3000; 2767 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2758 2768
2759 if (m_updateFlag == 1) 2769 if (m_updateFlag == 1)
2760 { 2770 {
@@ -2768,7 +2778,7 @@ namespace OpenSim.Region.Framework.Scenes
2768 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2778 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2769 { 2779 {
2770 AddTerseUpdateToAllAvatars(); 2780 AddTerseUpdateToAllAvatars();
2771 ClearUpdateSchedule(); 2781
2772 2782
2773 // This causes the Scene to 'poll' physical objects every couple of frames 2783 // This causes the Scene to 'poll' physical objects every couple of frames
2774 // bad, so it's been replaced by an event driven method. 2784 // bad, so it's been replaced by an event driven method.
@@ -2786,16 +2796,18 @@ namespace OpenSim.Region.Framework.Scenes
2786 m_lastAngularVelocity = AngularVelocity; 2796 m_lastAngularVelocity = AngularVelocity;
2787 m_lastTerseSent = Environment.TickCount; 2797 m_lastTerseSent = Environment.TickCount;
2788 } 2798 }
2799 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2800 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2789 } 2801 }
2790 else 2802 else
2791 { 2803 {
2792 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2804 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2793 { 2805 {
2794 AddFullUpdateToAllAvatars(); 2806 AddFullUpdateToAllAvatars();
2795 ClearUpdateSchedule(); 2807 m_updateFlag = 0; //Same here
2796 } 2808 }
2797 } 2809 }
2798 ClearUpdateSchedule(); 2810 m_updateFlag = 0;
2799 } 2811 }
2800 2812
2801 /// <summary> 2813 /// <summary>
@@ -2822,17 +2834,16 @@ namespace OpenSim.Region.Framework.Scenes
2822 if (!UUID.TryParse(sound, out soundID)) 2834 if (!UUID.TryParse(sound, out soundID))
2823 { 2835 {
2824 // search sound file from inventory 2836 // search sound file from inventory
2825 lock (TaskInventory) 2837 TaskInventory.LockItemsForRead(true);
2838 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2826 { 2839 {
2827 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2840 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2828 { 2841 {
2829 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2842 soundID = item.Value.ItemID;
2830 { 2843 break;
2831 soundID = item.Value.ItemID;
2832 break;
2833 }
2834 } 2844 }
2835 } 2845 }
2846 TaskInventory.LockItemsForRead(false);
2836 } 2847 }
2837 2848
2838 if (soundID == UUID.Zero) 2849 if (soundID == UUID.Zero)
@@ -2974,6 +2985,22 @@ namespace OpenSim.Region.Framework.Scenes
2974 PhysActor.VehicleRotationParam(param, rotation); 2985 PhysActor.VehicleRotationParam(param, rotation);
2975 } 2986 }
2976 } 2987 }
2988
2989 public void SetVehicleFlags(int flags)
2990 {
2991 if (PhysActor != null)
2992 {
2993 PhysActor.VehicleFlagsSet(flags);
2994 }
2995 }
2996
2997 public void RemoveVehicleFlags(int flags)
2998 {
2999 if (PhysActor != null)
3000 {
3001 PhysActor.VehicleFlagsRemove(flags);
3002 }
3003 }
2977 3004
2978 /// <summary> 3005 /// <summary>
2979 /// Set the color of prim faces 3006 /// Set the color of prim faces
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index b37e1a2..3317dd3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -82,7 +82,9 @@ namespace OpenSim.Region.Framework.Scenes
82 /// </value> 82 /// </value>
83 protected internal TaskInventoryDictionary Items 83 protected internal TaskInventoryDictionary Items
84 { 84 {
85 get { return m_items; } 85 get {
86 return m_items;
87 }
86 set 88 set
87 { 89 {
88 m_items = value; 90 m_items = value;
@@ -118,22 +120,25 @@ namespace OpenSim.Region.Framework.Scenes
118 /// <param name="linkNum">Link number for the part</param> 120 /// <param name="linkNum">Link number for the part</param>
119 public void ResetInventoryIDs() 121 public void ResetInventoryIDs()
120 { 122 {
121 lock (Items) 123 m_items.LockItemsForWrite(true);
124
125 if (0 == Items.Count)
122 { 126 {
123 if (0 == Items.Count) 127 m_items.LockItemsForWrite(false);
124 return; 128 return;
129 }
125 130
126 HasInventoryChanged = true; 131 HasInventoryChanged = true;
127 m_part.ParentGroup.HasGroupChanged = true; 132 m_part.ParentGroup.HasGroupChanged = true;
128 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 133 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
129 Items.Clear(); 134 Items.Clear();
130 135
131 foreach (TaskInventoryItem item in items) 136 foreach (TaskInventoryItem item in items)
132 { 137 {
133 item.ResetIDs(m_part.UUID); 138 item.ResetIDs(m_part.UUID);
134 Items.Add(item.ItemID, item); 139 Items.Add(item.ItemID, item);
135 }
136 } 140 }
141 m_items.LockItemsForWrite(false);
137 } 142 }
138 143
139 /// <summary> 144 /// <summary>
@@ -142,25 +147,25 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <param name="ownerId"></param> 147 /// <param name="ownerId"></param>
143 public void ChangeInventoryOwner(UUID ownerId) 148 public void ChangeInventoryOwner(UUID ownerId)
144 { 149 {
145 lock (Items) 150 m_items.LockItemsForWrite(true);
151 if (0 == Items.Count)
146 { 152 {
147 if (0 == Items.Count) 153 m_items.LockItemsForWrite(false);
148 { 154 return;
149 return; 155 }
150 }
151 156
152 HasInventoryChanged = true; 157 HasInventoryChanged = true;
153 m_part.ParentGroup.HasGroupChanged = true; 158 m_part.ParentGroup.HasGroupChanged = true;
154 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 159 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
155 foreach (TaskInventoryItem item in items) 160 foreach (TaskInventoryItem item in items)
161 {
162 if (ownerId != item.OwnerID)
156 { 163 {
157 if (ownerId != item.OwnerID) 164 item.LastOwnerID = item.OwnerID;
158 { 165 item.OwnerID = ownerId;
159 item.LastOwnerID = item.OwnerID;
160 item.OwnerID = ownerId;
161 }
162 } 166 }
163 } 167 }
168 m_items.LockItemsForWrite(false);
164 } 169 }
165 170
166 /// <summary> 171 /// <summary>
@@ -169,24 +174,24 @@ namespace OpenSim.Region.Framework.Scenes
169 /// <param name="groupID"></param> 174 /// <param name="groupID"></param>
170 public void ChangeInventoryGroup(UUID groupID) 175 public void ChangeInventoryGroup(UUID groupID)
171 { 176 {
172 lock (Items) 177 m_items.LockItemsForWrite(true);
178 if (0 == Items.Count)
173 { 179 {
174 if (0 == Items.Count) 180 m_items.LockItemsForWrite(false);
175 { 181 return;
176 return; 182 }
177 }
178 183
179 HasInventoryChanged = true; 184 HasInventoryChanged = true;
180 m_part.ParentGroup.HasGroupChanged = true; 185 m_part.ParentGroup.HasGroupChanged = true;
181 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 186 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
182 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
188 {
189 if (groupID != item.GroupID)
183 { 190 {
184 if (groupID != item.GroupID) 191 item.GroupID = groupID;
185 {
186 item.GroupID = groupID;
187 }
188 } 192 }
189 } 193 }
194 m_items.LockItemsForWrite(false);
190 } 195 }
191 196
192 /// <summary> 197 /// <summary>
@@ -194,14 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
194 /// </summary> 199 /// </summary>
195 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 200 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
196 { 201 {
197 lock (m_items) 202 Items.LockItemsForRead(true);
203 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
204 Items.LockItemsForRead(false);
205 foreach (TaskInventoryItem item in items)
198 { 206 {
199 foreach (TaskInventoryItem item in Items.Values) 207 if ((int)InventoryType.LSL == item.InvType)
200 { 208 {
201 if ((int)InventoryType.LSL == item.InvType) 209 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 {
203 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
204 }
205 } 210 }
206 } 211 }
207 } 212 }
@@ -236,16 +241,20 @@ namespace OpenSim.Region.Framework.Scenes
236 /// </param> 241 /// </param>
237 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 242 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
238 { 243 {
239 lock (Items) 244 Items.LockItemsForRead(true);
245 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
246 Items.LockItemsForRead(false);
247
248 foreach (TaskInventoryItem item in items)
240 { 249 {
241 foreach (TaskInventoryItem item in Items.Values) 250 if ((int)InventoryType.LSL == item.InvType)
242 { 251 {
243 if ((int)InventoryType.LSL == item.InvType) 252 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
244 { 253 m_part.RemoveScriptEvents(item.ItemID);
245 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
246 }
247 } 254 }
248 } 255 }
256
257
249 } 258 }
250 259
251 /// <summary> 260 /// <summary>
@@ -270,8 +279,10 @@ namespace OpenSim.Region.Framework.Scenes
270 if (stateSource == 1 && // Prim crossing 279 if (stateSource == 1 && // Prim crossing
271 m_part.ParentGroup.Scene.m_trustBinaries) 280 m_part.ParentGroup.Scene.m_trustBinaries)
272 { 281 {
282 m_items.LockItemsForWrite(true);
273 m_items[item.ItemID].PermsMask = 0; 283 m_items[item.ItemID].PermsMask = 0;
274 m_items[item.ItemID].PermsGranter = UUID.Zero; 284 m_items[item.ItemID].PermsGranter = UUID.Zero;
285 m_items.LockItemsForWrite(false);
275 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 286 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
276 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 287 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
277 m_part.ParentGroup.AddActiveScriptCount(1); 288 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -293,8 +304,10 @@ namespace OpenSim.Region.Framework.Scenes
293 { 304 {
294 if (m_part.ParentGroup.m_savedScriptState != null) 305 if (m_part.ParentGroup.m_savedScriptState != null)
295 RestoreSavedScriptState(item.OldItemID, item.ItemID); 306 RestoreSavedScriptState(item.OldItemID, item.ItemID);
307 m_items.LockItemsForWrite(true);
296 m_items[item.ItemID].PermsMask = 0; 308 m_items[item.ItemID].PermsMask = 0;
297 m_items[item.ItemID].PermsGranter = UUID.Zero; 309 m_items[item.ItemID].PermsGranter = UUID.Zero;
310 m_items.LockItemsForWrite(false);
298 string script = Utils.BytesToString(asset.Data); 311 string script = Utils.BytesToString(asset.Data);
299 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 312 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
300 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 313 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -370,14 +383,17 @@ namespace OpenSim.Region.Framework.Scenes
370 /// </param> 383 /// </param>
371 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 384 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
372 { 385 {
373 lock (m_items) 386 m_items.LockItemsForRead(true);
387 if (m_items.ContainsKey(itemId))
374 { 388 {
375 if (m_items.ContainsKey(itemId)) 389 if (m_items.ContainsKey(itemId))
376 { 390 {
391 m_items.LockItemsForRead(false);
377 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 392 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
378 } 393 }
379 else 394 else
380 { 395 {
396 m_items.LockItemsForRead(false);
381 m_log.ErrorFormat( 397 m_log.ErrorFormat(
382 "[PRIM INVENTORY]: " + 398 "[PRIM INVENTORY]: " +
383 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 399 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -385,6 +401,15 @@ namespace OpenSim.Region.Framework.Scenes
385 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 401 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
386 } 402 }
387 } 403 }
404 else
405 {
406 m_items.LockItemsForRead(false);
407 m_log.ErrorFormat(
408 "[PRIM INVENTORY]: " +
409 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
410 itemId, m_part.Name, m_part.UUID);
411 }
412
388 } 413 }
389 414
390 /// <summary> 415 /// <summary>
@@ -423,11 +448,16 @@ namespace OpenSim.Region.Framework.Scenes
423 /// <returns></returns> 448 /// <returns></returns>
424 private bool InventoryContainsName(string name) 449 private bool InventoryContainsName(string name)
425 { 450 {
426 foreach (TaskInventoryItem item in Items.Values) 451 m_items.LockItemsForRead(true);
452 foreach (TaskInventoryItem item in m_items.Values)
427 { 453 {
428 if (item.Name == name) 454 if (item.Name == name)
455 {
456 m_items.LockItemsForRead(false);
429 return true; 457 return true;
458 }
430 } 459 }
460 m_items.LockItemsForRead(false);
431 return false; 461 return false;
432 } 462 }
433 463
@@ -469,7 +499,9 @@ namespace OpenSim.Region.Framework.Scenes
469 /// <param name="item"></param> 499 /// <param name="item"></param>
470 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 500 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
471 { 501 {
502 m_items.LockItemsForRead(true);
472 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 503 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
504 m_items.LockItemsForRead(false);
473 foreach (TaskInventoryItem i in il) 505 foreach (TaskInventoryItem i in il)
474 { 506 {
475 if (i.Name == item.Name) 507 if (i.Name == item.Name)
@@ -506,15 +538,14 @@ namespace OpenSim.Region.Framework.Scenes
506 item.ParentPartID = m_part.UUID; 538 item.ParentPartID = m_part.UUID;
507 item.Name = name; 539 item.Name = name;
508 540
509 lock (m_items) 541 m_items.LockItemsForWrite(true);
510 { 542 m_items.Add(item.ItemID, item);
511 m_items.Add(item.ItemID, item); 543 m_items.LockItemsForWrite(false);
512
513 if (allowedDrop) 544 if (allowedDrop)
514 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 545 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
515 else 546 else
516 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 547 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
517 } 548
518 549
519 m_inventorySerial++; 550 m_inventorySerial++;
520 //m_inventorySerial += 2; 551 //m_inventorySerial += 2;
@@ -531,14 +562,13 @@ namespace OpenSim.Region.Framework.Scenes
531 /// <param name="items"></param> 562 /// <param name="items"></param>
532 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 563 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
533 { 564 {
534 lock (m_items) 565 m_items.LockItemsForWrite(true);
566 foreach (TaskInventoryItem item in items)
535 { 567 {
536 foreach (TaskInventoryItem item in items) 568 m_items.Add(item.ItemID, item);
537 { 569 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
538 m_items.Add(item.ItemID, item);
539 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
540 }
541 } 570 }
571 m_items.LockItemsForWrite(false);
542 572
543 m_inventorySerial++; 573 m_inventorySerial++;
544 } 574 }
@@ -551,8 +581,9 @@ namespace OpenSim.Region.Framework.Scenes
551 public TaskInventoryItem GetInventoryItem(UUID itemId) 581 public TaskInventoryItem GetInventoryItem(UUID itemId)
552 { 582 {
553 TaskInventoryItem item; 583 TaskInventoryItem item;
584 m_items.LockItemsForRead(true);
554 m_items.TryGetValue(itemId, out item); 585 m_items.TryGetValue(itemId, out item);
555 586 m_items.LockItemsForRead(false);
556 return item; 587 return item;
557 } 588 }
558 589
@@ -588,46 +619,46 @@ namespace OpenSim.Region.Framework.Scenes
588 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 619 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
589 public bool UpdateInventoryItem(TaskInventoryItem item) 620 public bool UpdateInventoryItem(TaskInventoryItem item)
590 { 621 {
591 lock (m_items) 622 m_items.LockItemsForWrite(true);
623
624 if (m_items.ContainsKey(item.ItemID))
592 { 625 {
593 if (m_items.ContainsKey(item.ItemID)) 626 item.ParentID = m_part.UUID;
627 item.ParentPartID = m_part.UUID;
628 item.Flags = m_items[item.ItemID].Flags;
629 if (item.AssetID == UUID.Zero)
594 { 630 {
595 item.ParentID = m_part.UUID; 631 item.AssetID = m_items[item.ItemID].AssetID;
596 item.ParentPartID = m_part.UUID; 632 }
597 item.Flags = m_items[item.ItemID].Flags; 633 else if ((InventoryType)item.Type == InventoryType.Notecard)
598 if (item.AssetID == UUID.Zero) 634 {
599 { 635 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
600 item.AssetID = m_items[item.ItemID].AssetID;
601 }
602 else if ((InventoryType)item.Type == InventoryType.Notecard)
603 {
604 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
605 636
606 if (presence != null) 637 if (presence != null)
607 { 638 {
608 presence.ControllingClient.SendAgentAlertMessage( 639 presence.ControllingClient.SendAgentAlertMessage(
609 "Notecard saved", false); 640 "Notecard saved", false);
610 }
611 } 641 }
642 }
612 643
613 m_items[item.ItemID] = item; 644 m_items[item.ItemID] = item;
614 m_inventorySerial++; 645 m_inventorySerial++;
615 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 646 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
616
617 HasInventoryChanged = true;
618 m_part.ParentGroup.HasGroupChanged = true;
619 647
620 return true; 648 HasInventoryChanged = true;
621 } 649 m_part.ParentGroup.HasGroupChanged = true;
622 else 650 m_items.LockItemsForWrite(false);
623 { 651 return true;
624 m_log.ErrorFormat( 652 }
625 "[PRIM INVENTORY]: " + 653 else
626 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 654 {
627 item.ItemID, m_part.Name, m_part.UUID, 655 m_log.ErrorFormat(
628 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 656 "[PRIM INVENTORY]: " +
629 } 657 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
658 item.ItemID, m_part.Name, m_part.UUID,
659 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
630 } 660 }
661 m_items.LockItemsForWrite(false);
631 662
632 return false; 663 return false;
633 } 664 }
@@ -640,53 +671,54 @@ namespace OpenSim.Region.Framework.Scenes
640 /// in this prim's inventory.</returns> 671 /// in this prim's inventory.</returns>
641 public int RemoveInventoryItem(UUID itemID) 672 public int RemoveInventoryItem(UUID itemID)
642 { 673 {
643 lock (m_items) 674 m_items.LockItemsForRead(true);
675
676 if (m_items.ContainsKey(itemID))
644 { 677 {
645 if (m_items.ContainsKey(itemID)) 678 int type = m_items[itemID].InvType;
679 m_items.LockItemsForRead(false);
680 if (type == 10) // Script
646 { 681 {
647 int type = m_items[itemID].InvType; 682 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
648 if (type == 10) // Script 683 }
649 { 684 m_items.LockItemsForWrite(true);
650 m_part.RemoveScriptEvents(itemID); 685 m_items.Remove(itemID);
651 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 686 m_items.LockItemsForWrite(false);
652 } 687 m_inventorySerial++;
653 m_items.Remove(itemID); 688 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
654 m_inventorySerial++;
655 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
656
657 HasInventoryChanged = true;
658 m_part.ParentGroup.HasGroupChanged = true;
659 689
660 int scriptcount = 0; 690 HasInventoryChanged = true;
661 lock (m_items) 691 m_part.ParentGroup.HasGroupChanged = true;
662 {
663 foreach (TaskInventoryItem item in m_items.Values)
664 {
665 if (item.Type == 10)
666 {
667 scriptcount++;
668 }
669 }
670 }
671 692
672 if (scriptcount <= 0) 693 int scriptcount = 0;
694 m_items.LockItemsForRead(true);
695 foreach (TaskInventoryItem item in m_items.Values)
696 {
697 if (item.Type == 10)
673 { 698 {
674 m_part.RemFlag(PrimFlags.Scripted); 699 scriptcount++;
675 } 700 }
676
677 m_part.ScheduleFullUpdate();
678
679 return type;
680 } 701 }
681 else 702 m_items.LockItemsForRead(false);
703
704
705 if (scriptcount <= 0)
682 { 706 {
683 m_log.ErrorFormat( 707 m_part.RemFlag(PrimFlags.Scripted);
684 "[PRIM INVENTORY]: " +
685 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
686 itemID, m_part.Name, m_part.UUID,
687 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
688 } 708 }
709
710 m_part.ScheduleFullUpdate();
711
712 return type;
713 }
714 else
715 {
716 m_log.ErrorFormat(
717 "[PRIM INVENTORY]: " +
718 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
719 itemID, m_part.Name, m_part.UUID);
689 } 720 }
721 m_items.LockItemsForWrite(false);
690 722
691 return -1; 723 return -1;
692 } 724 }
@@ -739,52 +771,53 @@ namespace OpenSim.Region.Framework.Scenes
739 // isn't available (such as drag from prim inventory to agent inventory) 771 // isn't available (such as drag from prim inventory to agent inventory)
740 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 772 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
741 773
742 lock (m_items) 774 m_items.LockItemsForRead(true);
775
776 foreach (TaskInventoryItem item in m_items.Values)
743 { 777 {
744 foreach (TaskInventoryItem item in m_items.Values) 778 UUID ownerID = item.OwnerID;
745 { 779 uint everyoneMask = 0;
746 UUID ownerID = item.OwnerID; 780 uint baseMask = item.BasePermissions;
747 uint everyoneMask = 0; 781 uint ownerMask = item.CurrentPermissions;
748 uint baseMask = item.BasePermissions;
749 uint ownerMask = item.CurrentPermissions;
750 782
751 invString.AddItemStart(); 783 invString.AddItemStart();
752 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 784 invString.AddNameValueLine("item_id", item.ItemID.ToString());
753 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 785 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
754 786
755 invString.AddPermissionsStart(); 787 invString.AddPermissionsStart();
756 788
757 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 789 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
758 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 790 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
759 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 791 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
760 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 792 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
761 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 793 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
762 794
763 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 795 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
764 invString.AddNameValueLine("owner_id", ownerID.ToString()); 796 invString.AddNameValueLine("owner_id", ownerID.ToString());
765 797
766 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 798 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
767 799
768 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 800 invString.AddNameValueLine("group_id", item.GroupID.ToString());
769 invString.AddSectionEnd(); 801 invString.AddSectionEnd();
770 802
771 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 803 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
772 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 804 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
773 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 805 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
774 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 806 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
775 807
776 invString.AddSaleStart(); 808 invString.AddSaleStart();
777 invString.AddNameValueLine("sale_type", "not"); 809 invString.AddNameValueLine("sale_type", "not");
778 invString.AddNameValueLine("sale_price", "0"); 810 invString.AddNameValueLine("sale_price", "0");
779 invString.AddSectionEnd(); 811 invString.AddSectionEnd();
780 812
781 invString.AddNameValueLine("name", item.Name + "|"); 813 invString.AddNameValueLine("name", item.Name + "|");
782 invString.AddNameValueLine("desc", item.Description + "|"); 814 invString.AddNameValueLine("desc", item.Description + "|");
783 815
784 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 816 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
785 invString.AddSectionEnd(); 817 invString.AddSectionEnd();
786 }
787 } 818 }
819 int count = m_items.Count;
820 m_items.LockItemsForRead(false);
788 821
789 fileData = Utils.StringToBytes(invString.BuildString); 822 fileData = Utils.StringToBytes(invString.BuildString);
790 823
@@ -805,10 +838,9 @@ namespace OpenSim.Region.Framework.Scenes
805 { 838 {
806 if (HasInventoryChanged) 839 if (HasInventoryChanged)
807 { 840 {
808 lock (Items) 841 Items.LockItemsForRead(true);
809 { 842 datastore.StorePrimInventory(m_part.UUID, Items.Values);
810 datastore.StorePrimInventory(m_part.UUID, Items.Values); 843 Items.LockItemsForRead(false);
811 }
812 844
813 HasInventoryChanged = false; 845 HasInventoryChanged = false;
814 } 846 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e26283d..27df3b2 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,8 +115,11 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -124,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
124 private Vector3? m_forceToApply; 129 private Vector3? m_forceToApply;
125 private uint m_requestedSitTargetID; 130 private uint m_requestedSitTargetID;
126 private UUID m_requestedSitTargetUUID; 131 private UUID m_requestedSitTargetUUID;
127 public bool SitGround = false;
128 132
129 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 133 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
130 134
@@ -146,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
146 private int m_perfMonMS; 150 private int m_perfMonMS;
147 151
148 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
149
150 private bool m_forceFly; 153 private bool m_forceFly;
151 private bool m_flyDisabled; 154 private bool m_flyDisabled;
152 155
@@ -170,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
170 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
171 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
172 175
173 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 176 private readonly Vector3[] Dir_Vectors = new Vector3[11];
177 private bool m_isNudging = false;
174 178
175 // Position of agent's camera in world (region cordinates) 179 // Position of agent's camera in world (region cordinates)
176 protected Vector3 m_CameraCenter; 180 protected Vector3 m_CameraCenter;
@@ -195,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
195 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
196 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
197 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
198 203
199 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
200 205
@@ -205,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_followCamAuto; 210 private bool m_followCamAuto;
206 211
207 private int m_movementUpdateCount; 212 private int m_movementUpdateCount;
213 private int m_lastColCount = -1; //KF: Look for Collision chnages
214 private int m_updateCount = 0; //KF: Update Anims for a while
215 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
208 216
209 private const int NumMovementsBetweenRayCast = 5; 217 private const int NumMovementsBetweenRayCast = 5;
210 218
@@ -235,7 +243,9 @@ namespace OpenSim.Region.Framework.Scenes
235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 246 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
247 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
248 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
239 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
240 } 250 }
241 251
@@ -661,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
661 671
662 672
663 AdjustKnownSeeds(); 673 AdjustKnownSeeds();
664
665 // TODO: I think, this won't send anything, as we are still a child here...
666 Animator.TrySetMovementAnimation("STAND"); 674 Animator.TrySetMovementAnimation("STAND");
667
668 // we created a new ScenePresence (a new child agent) in a fresh region. 675 // we created a new ScenePresence (a new child agent) in a fresh region.
669 // Request info about all the (root) agents in this region 676 // Request info about all the (root) agents in this region
670 // Note: This won't send data *to* other clients in that region (children don't send) 677 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -720,25 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
720 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 727 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
721 Dir_Vectors[4] = Vector3.UnitZ; //UP 728 Dir_Vectors[4] = Vector3.UnitZ; //UP
722 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 729 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
723 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 730 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
724 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 731 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
725 Dir_Vectors[7] = -Vector3.UnitX; //BACK 732 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
733 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
734 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
726 } 735 }
727 736
728 private Vector3[] GetWalkDirectionVectors() 737 private Vector3[] GetWalkDirectionVectors()
729 { 738 {
730 Vector3[] vector = new Vector3[9]; 739 Vector3[] vector = new Vector3[11];
731 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 740 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
732 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 741 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
733 vector[2] = Vector3.UnitY; //LEFT 742 vector[2] = Vector3.UnitY; //LEFT
734 vector[3] = -Vector3.UnitY; //RIGHT 743 vector[3] = -Vector3.UnitY; //RIGHT
735 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 744 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
736 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 745 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
737 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 746 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
738 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 747 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
739 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 748 vector[8] = Vector3.UnitY; //LEFT_NUDGE
749 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
750 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
740 return vector; 751 return vector;
741 } 752 }
753
754 private bool[] GetDirectionIsNudge()
755 {
756 bool[] isNudge = new bool[11];
757 isNudge[0] = false; //FORWARD
758 isNudge[1] = false; //BACK
759 isNudge[2] = false; //LEFT
760 isNudge[3] = false; //RIGHT
761 isNudge[4] = false; //UP
762 isNudge[5] = false; //DOWN
763 isNudge[6] = true; //FORWARD_NUDGE
764 isNudge[7] = true; //BACK_NUDGE
765 isNudge[8] = true; //LEFT_NUDGE
766 isNudge[9] = true; //RIGHT_NUDGE
767 isNudge[10] = true; //DOWN_Nudge
768 return isNudge;
769 }
770
742 771
743 #endregion 772 #endregion
744 773
@@ -807,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes
807 { 836 {
808 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 837 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
809 pos.Y = crossedBorder.BorderLine.Z - 1; 838 pos.Y = crossedBorder.BorderLine.Z - 1;
839 }
840
841 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
842 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
843 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
844 if (KnownChildRegionHandles.Count == 0)
845 {
846 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
847 if (land != null)
848 {
849 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
850 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
851 {
852 pos = land.LandData.UserLocation;
853 }
854 }
810 } 855 }
811 856
812
813 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 857 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
814 { 858 {
815 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 859 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -944,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes
944 public void Teleport(Vector3 pos) 988 public void Teleport(Vector3 pos)
945 { 989 {
946 bool isFlying = false; 990 bool isFlying = false;
947 if (m_physicsActor != null)
948 isFlying = m_physicsActor.Flying;
949 991
992 if (m_physicsActor != null)
993 isFlying = m_physicsActor.Flying;
994
950 RemoveFromPhysicalScene(); 995 RemoveFromPhysicalScene();
951 Velocity = Vector3.Zero; 996 Velocity = Vector3.Zero;
952 AbsolutePosition = pos; 997 AbsolutePosition = pos;
@@ -957,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes
957 SetHeight(m_appearance.AvatarHeight); 1002 SetHeight(m_appearance.AvatarHeight);
958 } 1003 }
959 1004
960 SendTerseUpdateToAllClients(); 1005 SendTerseUpdateToAllClients();
1006
961 } 1007 }
962 1008
963 public void TeleportWithMomentum(Vector3 pos) 1009 public void TeleportWithMomentum(Vector3 pos)
@@ -1002,7 +1048,9 @@ namespace OpenSim.Region.Framework.Scenes
1002 { 1048 {
1003 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1049 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1004 } 1050 }
1005 1051
1052 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1053
1006 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1054 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1007 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1055 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1008 } 1056 }
@@ -1237,7 +1285,6 @@ namespace OpenSim.Region.Framework.Scenes
1237 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1285 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1238 } 1286 }
1239 } 1287 }
1240
1241 lock (scriptedcontrols) 1288 lock (scriptedcontrols)
1242 { 1289 {
1243 if (scriptedcontrols.Count > 0) 1290 if (scriptedcontrols.Count > 0)
@@ -1252,12 +1299,8 @@ namespace OpenSim.Region.Framework.Scenes
1252 1299
1253 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1300 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1254 { 1301 {
1255 // TODO: This doesn't prevent the user from walking yet. 1302 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1256 // Setting parent ID would fix this, if we knew what value 1303 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1257 // to use. Or we could add a m_isSitting variable.
1258 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1259 SitGround = true;
1260
1261 } 1304 }
1262 1305
1263 // In the future, these values might need to go global. 1306 // In the future, these values might need to go global.
@@ -1307,6 +1350,11 @@ namespace OpenSim.Region.Framework.Scenes
1307 update_rotation = true; 1350 update_rotation = true;
1308 } 1351 }
1309 1352
1353 //guilty until proven innocent..
1354 bool Nudging = true;
1355 //Basically, if there is at least one non-nudge control then we don't need
1356 //to worry about stopping the avatar
1357
1310 if (m_parentID == 0) 1358 if (m_parentID == 0)
1311 { 1359 {
1312 bool bAllowUpdateMoveToPosition = false; 1360 bool bAllowUpdateMoveToPosition = false;
@@ -1321,9 +1369,12 @@ namespace OpenSim.Region.Framework.Scenes
1321 else 1369 else
1322 dirVectors = Dir_Vectors; 1370 dirVectors = Dir_Vectors;
1323 1371
1324 // The fact that m_movementflag is a byte needs to be fixed 1372 bool[] isNudge = GetDirectionIsNudge();
1325 // it really should be a uint 1373
1326 uint nudgehack = 250; 1374
1375
1376
1377
1327 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1378 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1328 { 1379 {
1329 if (((uint)flags & (uint)DCF) != 0) 1380 if (((uint)flags & (uint)DCF) != 0)
@@ -1333,40 +1384,28 @@ namespace OpenSim.Region.Framework.Scenes
1333 try 1384 try
1334 { 1385 {
1335 agent_control_v3 += dirVectors[i]; 1386 agent_control_v3 += dirVectors[i];
1336 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1387 if (isNudge[i] == false)
1388 {
1389 Nudging = false;
1390 }
1337 } 1391 }
1338 catch (IndexOutOfRangeException) 1392 catch (IndexOutOfRangeException)
1339 { 1393 {
1340 // Why did I get this? 1394 // Why did I get this?
1341 } 1395 }
1342 1396
1343 if ((m_movementflag & (byte)(uint)DCF) == 0) 1397 if ((m_movementflag & (uint)DCF) == 0)
1344 { 1398 {
1345 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1346 {
1347 m_movementflag |= (byte)nudgehack;
1348 }
1349 m_movementflag += (byte)(uint)DCF; 1399 m_movementflag += (byte)(uint)DCF;
1350 update_movementflag = true; 1400 update_movementflag = true;
1351 } 1401 }
1352 } 1402 }
1353 else 1403 else
1354 { 1404 {
1355 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1405 if ((m_movementflag & (uint)DCF) != 0)
1356 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1357 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1358 ) // This or is for Nudge forward
1359 { 1406 {
1360 m_movementflag -= ((byte)(uint)DCF); 1407 m_movementflag -= (byte)(uint)DCF;
1361
1362 update_movementflag = true; 1408 update_movementflag = true;
1363 /*
1364 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1365 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1366 {
1367 m_log.Debug("Removed Hack flag");
1368 }
1369 */
1370 } 1409 }
1371 else 1410 else
1372 { 1411 {
@@ -1410,6 +1449,9 @@ namespace OpenSim.Region.Framework.Scenes
1410 // Ignore z component of vector 1449 // Ignore z component of vector
1411 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1450 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1412 LocalVectorToTarget2D.Normalize(); 1451 LocalVectorToTarget2D.Normalize();
1452
1453 //We're not nudging
1454 Nudging = false;
1413 agent_control_v3 += LocalVectorToTarget2D; 1455 agent_control_v3 += LocalVectorToTarget2D;
1414 1456
1415 // update avatar movement flags. the avatar coordinate system is as follows: 1457 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1498,13 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes
1498 // m_log.DebugFormat( 1540 // m_log.DebugFormat(
1499 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1541 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1500 1542
1501 AddNewMovement(agent_control_v3, q); 1543 AddNewMovement(agent_control_v3, q, Nudging);
1502 1544
1503 1545
1504 } 1546 }
1505 } 1547 }
1506 1548
1507 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1549 if (update_movementflag)
1508 Animator.UpdateMovementAnimations(); 1550 Animator.UpdateMovementAnimations();
1509 1551
1510 m_scene.EventManager.TriggerOnClientMovement(this); 1552 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1519,7 +1561,6 @@ namespace OpenSim.Region.Framework.Scenes
1519 m_sitAtAutoTarget = false; 1561 m_sitAtAutoTarget = false;
1520 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1562 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1521 //proxy.PCode = (byte)PCode.ParticleSystem; 1563 //proxy.PCode = (byte)PCode.ParticleSystem;
1522
1523 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1564 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1524 proxyObjectGroup.AttachToScene(m_scene); 1565 proxyObjectGroup.AttachToScene(m_scene);
1525 1566
@@ -1561,7 +1602,7 @@ namespace OpenSim.Region.Framework.Scenes
1561 } 1602 }
1562 m_moveToPositionInProgress = true; 1603 m_moveToPositionInProgress = true;
1563 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1604 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1564 } 1605 }
1565 catch (Exception ex) 1606 catch (Exception ex)
1566 { 1607 {
1567 //Why did I get this error? 1608 //Why did I get this error?
@@ -1583,7 +1624,7 @@ namespace OpenSim.Region.Framework.Scenes
1583 Velocity = Vector3.Zero; 1624 Velocity = Vector3.Zero;
1584 SendFullUpdateToAllClients(); 1625 SendFullUpdateToAllClients();
1585 1626
1586 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1627 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1587 } 1628 }
1588 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1629 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1589 m_requestedSitTargetUUID = UUID.Zero; 1630 m_requestedSitTargetUUID = UUID.Zero;
@@ -1616,55 +1657,84 @@ namespace OpenSim.Region.Framework.Scenes
1616 /// </summary> 1657 /// </summary>
1617 public void StandUp() 1658 public void StandUp()
1618 { 1659 {
1619 if (SitGround)
1620 SitGround = false;
1621
1622 if (m_parentID != 0) 1660 if (m_parentID != 0)
1623 { 1661 {
1624 m_log.Debug("StandupCode Executed");
1625 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1662 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1626 if (part != null) 1663 if (part != null)
1627 { 1664 {
1665 part.TaskInventory.LockItemsForRead(true);
1628 TaskInventoryDictionary taskIDict = part.TaskInventory; 1666 TaskInventoryDictionary taskIDict = part.TaskInventory;
1629 if (taskIDict != null) 1667 if (taskIDict != null)
1630 { 1668 {
1631 lock (taskIDict) 1669 foreach (UUID taskID in taskIDict.Keys)
1632 { 1670 {
1633 foreach (UUID taskID in taskIDict.Keys) 1671 UnRegisterControlEventsToScript(LocalId, taskID);
1634 { 1672 taskIDict[taskID].PermsMask &= ~(
1635 UnRegisterControlEventsToScript(LocalId, taskID); 1673 2048 | //PERMISSION_CONTROL_CAMERA
1636 taskIDict[taskID].PermsMask &= ~( 1674 4); // PERMISSION_TAKE_CONTROLS
1637 2048 | //PERMISSION_CONTROL_CAMERA
1638 4); // PERMISSION_TAKE_CONTROLS
1639 }
1640 } 1675 }
1641
1642 } 1676 }
1677 part.TaskInventory.LockItemsForRead(false);
1643 // Reset sit target. 1678 // Reset sit target.
1644 if (part.GetAvatarOnSitTarget() == UUID) 1679 if (part.GetAvatarOnSitTarget() == UUID)
1645 part.SetAvatarOnSitTarget(UUID.Zero); 1680 part.SetAvatarOnSitTarget(UUID.Zero);
1646
1647 m_parentPosition = part.GetWorldPosition(); 1681 m_parentPosition = part.GetWorldPosition();
1648 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1682 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1649 } 1683 }
1650 1684 // part.GetWorldRotation() is the rotation of the object being sat on
1651 if (m_physicsActor == null) 1685 // Rotation is the sittiing Av's rotation
1652 { 1686
1653 AddToPhysicalScene(false); 1687 Quaternion partRot;
1688// if (part.LinkNum == 1)
1689// { // Root prim of linkset
1690// partRot = part.ParentGroup.RootPart.RotationOffset;
1691// }
1692// else
1693// { // single or child prim
1694
1695// }
1696 if (part == null) //CW: Part may be gone. llDie() for example.
1697 {
1698 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1699 }
1700 else
1701 {
1702 partRot = part.GetWorldRotation();
1703 }
1704
1705 Quaternion partIRot = Quaternion.Inverse(partRot);
1706
1707 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1708 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1709
1710
1711 if (m_physicsActor == null)
1712 {
1713 AddToPhysicalScene(false);
1714 }
1715 //CW: If the part isn't null then we can set the current position
1716 if (part != null)
1717 {
1718 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1719 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1720 part.IsOccupied = false;
1721 }
1722 else
1723 {
1724 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1725 AbsolutePosition = m_lastWorldPosition;
1654 } 1726 }
1655 1727
1656 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1728 m_parentPosition = Vector3.Zero;
1657 m_parentPosition = Vector3.Zero; 1729 m_parentID = 0;
1658
1659 m_parentID = 0;
1660 SendFullUpdateToAllClients(); 1730 SendFullUpdateToAllClients();
1661 m_requestedSitTargetID = 0; 1731 m_requestedSitTargetID = 0;
1732
1662 if ((m_physicsActor != null) && (m_avHeight > 0)) 1733 if ((m_physicsActor != null) && (m_avHeight > 0))
1663 { 1734 {
1664 SetHeight(m_avHeight); 1735 SetHeight(m_avHeight);
1665 } 1736 }
1666 } 1737 }
1667
1668 Animator.TrySetMovementAnimation("STAND"); 1738 Animator.TrySetMovementAnimation("STAND");
1669 } 1739 }
1670 1740
@@ -1695,13 +1765,9 @@ namespace OpenSim.Region.Framework.Scenes
1695 Vector3 avSitOffSet = part.SitTargetPosition; 1765 Vector3 avSitOffSet = part.SitTargetPosition;
1696 Quaternion avSitOrientation = part.SitTargetOrientation; 1766 Quaternion avSitOrientation = part.SitTargetOrientation;
1697 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1767 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1698 1768 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1699 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1769 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1700 bool SitTargetisSet = 1770 if (SitTargetisSet && !SitTargetOccupied)
1701 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1703
1704 if (SitTargetisSet && SitTargetUnOccupied)
1705 { 1771 {
1706 //switch the target to this prim 1772 //switch the target to this prim
1707 return part; 1773 return part;
@@ -1715,84 +1781,152 @@ namespace OpenSim.Region.Framework.Scenes
1715 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1781 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1716 { 1782 {
1717 bool autopilot = true; 1783 bool autopilot = true;
1784 Vector3 autopilotTarget = new Vector3();
1785 Quaternion sitOrientation = Quaternion.Identity;
1718 Vector3 pos = new Vector3(); 1786 Vector3 pos = new Vector3();
1719 Quaternion sitOrientation = pSitOrientation;
1720 Vector3 cameraEyeOffset = Vector3.Zero; 1787 Vector3 cameraEyeOffset = Vector3.Zero;
1721 Vector3 cameraAtOffset = Vector3.Zero; 1788 Vector3 cameraAtOffset = Vector3.Zero;
1722 bool forceMouselook = false; 1789 bool forceMouselook = false;
1723 1790
1724 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1791 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1725 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1792 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1726 if (part != null) 1793 if (part == null) return;
1727 { 1794
1728 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1795 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1729 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1796 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1730 1797
1731 // Is a sit target available? 1798 // part is the prim to sit on
1732 Vector3 avSitOffSet = part.SitTargetPosition; 1799 // offset is the world-ref vector distance from that prim center to the click-spot
1733 Quaternion avSitOrientation = part.SitTargetOrientation; 1800 // UUID is the UUID of the Avatar doing the clicking
1734 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1801
1735 1802 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1736 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1803
1737 bool SitTargetisSet = 1804 // Is a sit target available?
1738 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1805 Vector3 avSitOffSet = part.SitTargetPosition;
1739 ( 1806 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1807
1741 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1808 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1742 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1809 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1743 ) 1810 Quaternion partRot;
1744 )); 1811// if (part.LinkNum == 1)
1745 1812// { // Root prim of linkset
1746 if (SitTargetisSet && SitTargetUnOccupied) 1813// partRot = part.ParentGroup.RootPart.RotationOffset;
1747 { 1814// }
1748 part.SetAvatarOnSitTarget(UUID); 1815// else
1749 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1816// { // single or child prim
1750 sitOrientation = avSitOrientation; 1817 partRot = part.GetWorldRotation();
1751 autopilot = false; 1818// }
1752 } 1819 Quaternion partIRot = Quaternion.Inverse(partRot);
1753 1820//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1754 pos = part.AbsolutePosition + offset; 1821 // Sit analysis rewritten by KF 091125
1755 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1822 if (SitTargetisSet) // scipted sit
1756 //{ 1823 {
1757 // offset = pos; 1824 if (!part.IsOccupied)
1758 //autopilot = false; 1825 {
1759 //} 1826//Console.WriteLine("Scripted, unoccupied");
1760 if (m_physicsActor != null) 1827 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1761 { 1828 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1762 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1829 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1763 // We can remove the physicsActor until they stand up. 1830 autopilot = false; // Jump direct to scripted llSitPos()
1764 m_sitAvatarHeight = m_physicsActor.Size.Z; 1831 }
1765 1832 else
1766 if (autopilot) 1833 {
1767 { 1834//Console.WriteLine("Scripted, occupied");
1768 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1835 return;
1769 { 1836 }
1770 autopilot = false; 1837 }
1838 else // Not Scripted
1839 {
1840 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1841 {
1842 // large prim & offset, ignore if other Avs sitting
1843// offset.Z -= 0.05f;
1844 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1845 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1846
1847//Console.WriteLine(" offset ={0}", offset);
1848//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1849//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1850
1851 }
1852 else // small offset
1853 {
1854//Console.WriteLine("Small offset");
1855 if (!part.IsOccupied)
1856 {
1857 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1858 autopilotTarget = part.AbsolutePosition;
1859 }
1860 else return; // occupied small
1861 } // end large/small
1862 } // end Scripted/not
1863 cameraAtOffset = part.GetCameraAtOffset();
1864 cameraEyeOffset = part.GetCameraEyeOffset();
1865 forceMouselook = part.GetForceMouselook();
1866 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1867 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1771 1868
1772 RemoveFromPhysicalScene(); 1869 if (m_physicsActor != null)
1773 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1870 {
1774 } 1871 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1775 } 1872 // We can remove the physicsActor until they stand up.
1776 else 1873 m_sitAvatarHeight = m_physicsActor.Size.Z;
1874 if (autopilot)
1875 { // its not a scripted sit
1876// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1877 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1777 { 1878 {
1879 autopilot = false; // close enough
1880 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1881 Not using the part's position because returning the AV to the last known standing
1882 position is likely to be more friendly, isn't it? */
1778 RemoveFromPhysicalScene(); 1883 RemoveFromPhysicalScene();
1779 } 1884 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1885 } // else the autopilot will get us close
1886 }
1887 else
1888 { // its a scripted sit
1889 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1890 I *am* using the part's position this time because we have no real idea how far away
1891 the avatar is from the sit target. */
1892 RemoveFromPhysicalScene();
1780 } 1893 }
1781
1782 cameraAtOffset = part.GetCameraAtOffset();
1783 cameraEyeOffset = part.GetCameraEyeOffset();
1784 forceMouselook = part.GetForceMouselook();
1785 } 1894 }
1786 1895 else return; // physactor is null!
1787 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1896
1788 m_requestedSitTargetUUID = targetID; 1897 Vector3 offsetr; // = offset * partIRot;
1898 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1899 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1900 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1901 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1902 offsetr = offset * partIRot;
1903//
1904 // else
1905 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1906 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1907 // (offset * partRot);
1908 // }
1909
1910//Console.WriteLine(" ");
1911//Console.WriteLine("link number ={0}", part.LinkNum);
1912//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1913//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1914//Console.WriteLine("Click offst ={0}", offset);
1915//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1916//Console.WriteLine("offsetr ={0}", offsetr);
1917//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1918//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1919
1920 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1921 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1789 // This calls HandleAgentSit twice, once from here, and the client calls 1922 // This calls HandleAgentSit twice, once from here, and the client calls
1790 // HandleAgentSit itself after it gets to the location 1923 // HandleAgentSit itself after it gets to the location
1791 // It doesn't get to the location until we've moved them there though 1924 // It doesn't get to the location until we've moved them there though
1792 // which happens in HandleAgentSit :P 1925 // which happens in HandleAgentSit :P
1793 m_autopilotMoving = autopilot; 1926 m_autopilotMoving = autopilot;
1794 m_autoPilotTarget = pos; 1927 m_autoPilotTarget = autopilotTarget;
1795 m_sitAtAutoTarget = autopilot; 1928 m_sitAtAutoTarget = autopilot;
1929 m_initialSitTarget = autopilotTarget;
1796 if (!autopilot) 1930 if (!autopilot)
1797 HandleAgentSit(remoteClient, UUID); 1931 HandleAgentSit(remoteClient, UUID);
1798 } 1932 }
@@ -2087,31 +2221,65 @@ namespace OpenSim.Region.Framework.Scenes
2087 { 2221 {
2088 if (part != null) 2222 if (part != null)
2089 { 2223 {
2224//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2090 if (part.GetAvatarOnSitTarget() == UUID) 2225 if (part.GetAvatarOnSitTarget() == UUID)
2091 { 2226 {
2227//Console.WriteLine("Scripted Sit");
2228 // Scripted sit
2092 Vector3 sitTargetPos = part.SitTargetPosition; 2229 Vector3 sitTargetPos = part.SitTargetPosition;
2093 Quaternion sitTargetOrient = part.SitTargetOrientation; 2230 Quaternion sitTargetOrient = part.SitTargetOrientation;
2094
2095 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2096 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2097
2098 //Quaternion result = (sitTargetOrient * vq) * nq;
2099
2100 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2231 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2101 m_pos += SIT_TARGET_ADJUSTMENT; 2232 m_pos += SIT_TARGET_ADJUSTMENT;
2102 m_bodyRot = sitTargetOrient; 2233 m_bodyRot = sitTargetOrient;
2103 //Rotation = sitTargetOrient;
2104 m_parentPosition = part.AbsolutePosition; 2234 m_parentPosition = part.AbsolutePosition;
2105 2235 part.IsOccupied = true;
2106 //SendTerseUpdateToAllClients();
2107 } 2236 }
2108 else 2237 else
2109 { 2238 {
2110 m_pos -= part.AbsolutePosition; 2239 // if m_avUnscriptedSitPos is zero then Av sits above center
2240 // Else Av sits at m_avUnscriptedSitPos
2241
2242 // Non-scripted sit by Kitto Flora 21Nov09
2243 // Calculate angle of line from prim to Av
2244 Quaternion partIRot;
2245// if (part.LinkNum == 1)
2246// { // Root prim of linkset
2247// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2248// }
2249// else
2250// { // single or child prim
2251 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2252// }
2253 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2254 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2255 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2256 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2257 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2258 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2259 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2260 // Av sits at world euler <0,0, z>, translated by part rotation
2261 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2262
2111 m_parentPosition = part.AbsolutePosition; 2263 m_parentPosition = part.AbsolutePosition;
2112 } 2264 part.IsOccupied = true;
2113 } 2265 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2114 else 2266 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2267 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2268 m_avUnscriptedSitPos; // adds click offset, if any
2269 //Set up raytrace to find top surface of prim
2270 Vector3 size = part.Scale;
2271 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2272 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2273 Vector3 down = new Vector3(0f, 0f, -1f);
2274//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2275 m_scene.PhysicsScene.RaycastWorld(
2276 start, // Vector3 position,
2277 down, // Vector3 direction,
2278 mag, // float length,
2279 SitAltitudeCallback); // retMethod
2280 } // end scripted/not
2281 }
2282 else // no Av
2115 { 2283 {
2116 return; 2284 return;
2117 } 2285 }
@@ -2123,11 +2291,36 @@ namespace OpenSim.Region.Framework.Scenes
2123 2291
2124 Animator.TrySetMovementAnimation(sitAnimation); 2292 Animator.TrySetMovementAnimation(sitAnimation);
2125 SendFullUpdateToAllClients(); 2293 SendFullUpdateToAllClients();
2126 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2127 // So we're also sending a terse update (which has avatar rotation)
2128 // [Update] We do now.
2129 //SendTerseUpdateToAllClients();
2130 } 2294 }
2295
2296 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2297 {
2298 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2299 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2300 if(hitYN)
2301 {
2302 // m_pos = Av offset from prim center to make look like on center
2303 // m_parentPosition = Actual center pos of prim
2304 // collisionPoint = spot on prim where we want to sit
2305 // collisionPoint.Z = global sit surface height
2306 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2307 Quaternion partIRot;
2308// if (part.LinkNum == 1)
2309/// { // Root prim of linkset
2310// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2311// }
2312// else
2313// { // single or child prim
2314 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2315// }
2316 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2317 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2318//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2319 m_pos += offset;
2320// ControllingClient.SendClearFollowCamProperties(part.UUID);
2321
2322 }
2323 } // End SitAltitudeCallback KF.
2131 2324
2132 /// <summary> 2325 /// <summary>
2133 /// Event handler for the 'Always run' setting on the client 2326 /// Event handler for the 'Always run' setting on the client
@@ -2157,7 +2350,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 /// </summary> 2350 /// </summary>
2158 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2351 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2159 /// <param name="rotation">The direction in which this avatar should now face. 2352 /// <param name="rotation">The direction in which this avatar should now face.
2160 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2353 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2161 { 2354 {
2162 if (m_isChildAgent) 2355 if (m_isChildAgent)
2163 { 2356 {
@@ -2231,7 +2424,7 @@ namespace OpenSim.Region.Framework.Scenes
2231 2424
2232 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2425 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2233 m_forceToApply = direc; 2426 m_forceToApply = direc;
2234 2427 m_isNudging = Nudging;
2235 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2428 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2236 } 2429 }
2237 2430
@@ -2246,7 +2439,7 @@ namespace OpenSim.Region.Framework.Scenes
2246 const float POSITION_TOLERANCE = 0.05f; 2439 const float POSITION_TOLERANCE = 0.05f;
2247 //const int TIME_MS_TOLERANCE = 3000; 2440 //const int TIME_MS_TOLERANCE = 3000;
2248 2441
2249 SendPrimUpdates(); 2442
2250 2443
2251 if (m_newCoarseLocations) 2444 if (m_newCoarseLocations)
2252 { 2445 {
@@ -2282,6 +2475,9 @@ namespace OpenSim.Region.Framework.Scenes
2282 CheckForBorderCrossing(); 2475 CheckForBorderCrossing();
2283 CheckForSignificantMovement(); // sends update to the modules. 2476 CheckForSignificantMovement(); // sends update to the modules.
2284 } 2477 }
2478
2479 //Sending prim updates AFTER the avatar terse updates are sent
2480 SendPrimUpdates();
2285 } 2481 }
2286 2482
2287 #endregion 2483 #endregion
@@ -3143,14 +3339,25 @@ namespace OpenSim.Region.Framework.Scenes
3143 { 3339 {
3144 if (m_forceToApply.HasValue) 3340 if (m_forceToApply.HasValue)
3145 { 3341 {
3146 Vector3 force = m_forceToApply.Value;
3147 3342
3343 Vector3 force = m_forceToApply.Value;
3148 m_updateflag = true; 3344 m_updateflag = true;
3149// movementvector = force;
3150 Velocity = force; 3345 Velocity = force;
3151 3346
3152 m_forceToApply = null; 3347 m_forceToApply = null;
3153 } 3348 }
3349 else
3350 {
3351 if (m_isNudging)
3352 {
3353 Vector3 force = Vector3.Zero;
3354
3355 m_updateflag = true;
3356 Velocity = force;
3357 m_isNudging = false;
3358 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3359 }
3360 }
3154 } 3361 }
3155 3362
3156 public override void SetText(string text, Vector3 color, double alpha) 3363 public override void SetText(string text, Vector3 color, double alpha)
@@ -3202,18 +3409,29 @@ namespace OpenSim.Region.Framework.Scenes
3202 { 3409 {
3203 if (e == null) 3410 if (e == null)
3204 return; 3411 return;
3205 3412
3206 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3413 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3207 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3208 // as of this comment the interval is set in AddToPhysicalScene 3414 // as of this comment the interval is set in AddToPhysicalScene
3209 if (Animator!=null) 3415 if (Animator!=null)
3210 Animator.UpdateMovementAnimations(); 3416 {
3417 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3418 { // else its will lock out other animation changes, like ground sit.
3419 Animator.UpdateMovementAnimations();
3420 m_updateCount--;
3421 }
3422 }
3211 3423
3212 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3424 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3213 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3425 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3214 3426
3215 CollisionPlane = Vector4.UnitW; 3427 CollisionPlane = Vector4.UnitW;
3216 3428
3429 if (m_lastColCount != coldata.Count)
3430 {
3431 m_updateCount = UPDATE_COUNT;
3432 m_lastColCount = coldata.Count;
3433 }
3434
3217 if (coldata.Count != 0 && Animator != null) 3435 if (coldata.Count != 0 && Animator != null)
3218 { 3436 {
3219 switch (Animator.CurrentMovementAnimation) 3437 switch (Animator.CurrentMovementAnimation)
@@ -3859,5 +4077,16 @@ namespace OpenSim.Region.Framework.Scenes
3859 m_reprioritization_called = false; 4077 m_reprioritization_called = false;
3860 } 4078 }
3861 } 4079 }
4080
4081 private Vector3 Quat2Euler(Quaternion rot){
4082 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4083 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4084 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4085 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4086 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4087 return(new Vector3(x,y,z));
4088 }
4089
4090
3862 } 4091 }
3863} 4092}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index e4296ef..1cff0eb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
76 76
77 foreach (EntityBase e in m_presence.Scene.Entities) 77 foreach (EntityBase e in m_presence.Scene.Entities)
78 { 78 {
79 if (e is SceneObjectGroup) 79 if (e != null && e is SceneObjectGroup)
80 m_pendingObjects.Enqueue((SceneObjectGroup)e); 80 m_pendingObjects.Enqueue((SceneObjectGroup)e);
81 } 81 }
82 } 82 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8a27b7b..5abbb82 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -101,7 +101,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 { 101 {
102 throw new NotImplementedException(); 102 throw new NotImplementedException();
103 } 103 }
104 104 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
105 {
106 //This connector doesn't support the windlight module yet
107 //Return default LL windlight settings
108 return new RegionMeta7WindlightData();
109 }
110 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
111 {
112 //This connector doesn't support the windlight module yet
113 }
105 public RegionSettings LoadRegionSettings(UUID regionUUID) 114 public RegionSettings LoadRegionSettings(UUID regionUUID)
106 { 115 {
107 return null; 116 return null;