aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs70
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs389
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs203
7 files changed, 463 insertions, 280 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index b37249d..ba11800 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -156,10 +156,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 157
158 // Check control flags 158 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 159 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);
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 160 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);
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 161 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);
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 162 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);
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 66fb918..83208e9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -840,8 +840,12 @@ namespace OpenSim.Region.Framework.Scenes
840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
841 { 841 {
842 SceneObjectPart part = GetSceneObjectPart(localID); 842 SceneObjectPart part = GetSceneObjectPart(localID);
843 SceneObjectGroup group = part.ParentGroup; 843 SceneObjectGroup group = null;
844 if (group != null) 844 if (part != null)
845 {
846 group = part.ParentGroup;
847 }
848 if (part != null && group != null)
845 { 849 {
846 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 850 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
847 if (item == null) 851 if (item == null)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index eb8567f..5b13b73 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -873,6 +873,15 @@ namespace OpenSim.Region.Framework.Scenes
873 /// <param name="seconds">float indicating duration before restart.</param> 873 /// <param name="seconds">float indicating duration before restart.</param>
874 public virtual void Restart(float seconds) 874 public virtual void Restart(float seconds)
875 { 875 {
876 Restart(seconds, true);
877 }
878
879 /// <summary>
880 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
881 /// </summary>
882 /// <param name="seconds">float indicating duration before restart.</param>
883 public virtual void Restart(float seconds, bool showDialog)
884 {
876 // notifications are done in 15 second increments 885 // notifications are done in 15 second increments
877 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 886 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
878 // It's a 'Cancel restart' request. 887 // It's a 'Cancel restart' request.
@@ -893,8 +902,11 @@ namespace OpenSim.Region.Framework.Scenes
893 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 902 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
894 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 903 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
895 m_restartTimer.Start(); 904 m_restartTimer.Start();
896 m_dialogModule.SendNotificationToUsersInRegion( 905 if (showDialog)
897 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes"); 906 {
907 m_dialogModule.SendNotificationToUsersInRegion(
908 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in " + (seconds / 60).ToString() + " Minutes");
909 }
898 } 910 }
899 } 911 }
900 912
@@ -1164,16 +1176,16 @@ namespace OpenSim.Region.Framework.Scenes
1164 // Check if any objects have reached their targets 1176 // Check if any objects have reached their targets
1165 CheckAtTargets(); 1177 CheckAtTargets();
1166 1178
1167 // Update SceneObjectGroups that have scheduled themselves for updates
1168 // Objects queue their updates onto all scene presences
1169 if (m_frame % m_update_objects == 0)
1170 m_sceneGraph.UpdateObjectGroups();
1171
1172 // Run through all ScenePresences looking for updates 1179 // Run through all ScenePresences looking for updates
1173 // Presence updates and queued object updates for each presence are sent to clients 1180 // Presence updates and queued object updates for each presence are sent to clients
1174 if (m_frame % m_update_presences == 0) 1181 if (m_frame % m_update_presences == 0)
1175 m_sceneGraph.UpdatePresences(); 1182 m_sceneGraph.UpdatePresences();
1176 1183
1184 // Update SceneObjectGroups that have scheduled themselves for updates
1185 // Objects queue their updates onto all scene presences
1186 if (m_frame % m_update_objects == 0)
1187 m_sceneGraph.UpdateObjectGroups();
1188
1177 int TempPhysicsMS2 = Environment.TickCount; 1189 int TempPhysicsMS2 = Environment.TickCount;
1178 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1190 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1179 m_sceneGraph.UpdatePreparePhysics(); 1191 m_sceneGraph.UpdatePreparePhysics();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6ec2a01..f36ff1d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1734,6 +1734,45 @@ namespace OpenSim.Region.Framework.Scenes
1734 } 1734 }
1735 } 1735 }
1736 1736
1737 public void rotLookAt(Quaternion target, float strength, float damping)
1738 {
1739 SceneObjectPart rootpart = m_rootPart;
1740 if (rootpart != null)
1741 {
1742 if (IsAttachment)
1743 {
1744 /*
1745 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1746 if (avatar != null)
1747 {
1748 Rotate the Av?
1749 } */
1750 }
1751 else
1752 {
1753 if (rootpart.PhysActor != null)
1754 {
1755 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1756 rootpart.PhysActor.APIDStrength = strength;
1757 rootpart.PhysActor.APIDDamping = damping;
1758 rootpart.PhysActor.APIDActive = true;
1759 }
1760 }
1761 }
1762 }
1763 public void stopLookAt()
1764 {
1765 SceneObjectPart rootpart = m_rootPart;
1766 if (rootpart != null)
1767 {
1768 if (rootpart.PhysActor != null)
1769 {
1770 rootpart.PhysActor.APIDActive = false;
1771 }
1772 }
1773
1774 }
1775
1737 /// <summary> 1776 /// <summary>
1738 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1777 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1739 /// </summary> 1778 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b6916f2..19e3023 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -389,12 +389,16 @@ namespace OpenSim.Region.Framework.Scenes
389 } 389 }
390 390
391 /// <value> 391 /// <value>
392 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 392 /// Get the inventory list
393 /// </value> 393 /// </value>
394 public TaskInventoryDictionary TaskInventory 394 public TaskInventoryDictionary TaskInventory
395 { 395 {
396 get { return m_inventory.Items; } 396 get {
397 set { m_inventory.Items = value; } 397 return m_inventory.Items;
398 }
399 set {
400 m_inventory.Items = value;
401 }
398 } 402 }
399 403
400 public uint ObjectFlags 404 public uint ObjectFlags
@@ -1064,14 +1068,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1068 }
1065 } 1069 }
1066 1070
1067 /// <summary>
1068 /// Clear all pending updates of parts to clients
1069 /// </summary>
1070 private void ClearUpdateSchedule()
1071 {
1072 m_updateFlag = 0;
1073 }
1074
1075 private void SendObjectPropertiesToClient(UUID AgentID) 1071 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1072 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1073 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -2109,17 +2105,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2105 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2106 //Prim's inventory doesn't support non script items yet
2111 2107
2112 lock (TaskInventory) 2108 TaskInventory.LockItemsForRead(true);
2109
2110 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2111 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2112 if (item.Value.Name == sound)
2115 { 2113 {
2116 if (item.Value.Name == sound) 2114 soundID = item.Value.ItemID;
2117 { 2115 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2116 }
2122 } 2117 }
2118
2119 TaskInventory.LockItemsForRead(false);
2123 } 2120 }
2124 2121
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2122 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2185,6 +2182,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2182 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2183 ScheduleFullUpdate();
2187 } 2184 }
2185
2186 public void RotLookAt(Quaternion target, float strength, float damping)
2187 {
2188 m_parentGroup.rotLookAt(target, strength, damping);
2189 }
2188 2190
2189 /// <summary> 2191 /// <summary>
2190 /// Schedules this prim for a full update 2192 /// Schedules this prim for a full update
@@ -2389,8 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2391 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2392 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2393 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2394 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2395 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2396
2395 if (m_updateFlag == 1) 2397 if (m_updateFlag == 1)
2396 { 2398 {
@@ -2404,7 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2406 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2407 {
2406 AddTerseUpdateToAllAvatars(); 2408 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2409
2408 2410
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2411 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2412 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2424,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2424 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2425 m_lastTerseSent = Environment.TickCount;
2424 } 2426 }
2427 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2428 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2429 }
2426 else 2430 else
2427 { 2431 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2432 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2433 {
2430 AddFullUpdateToAllAvatars(); 2434 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2435 m_updateFlag = 0; //Same here
2432 } 2436 }
2433 } 2437 }
2434 ClearUpdateSchedule(); 2438 m_updateFlag = 0;
2435 } 2439 }
2436 2440
2437 /// <summary> 2441 /// <summary>
@@ -2458,17 +2462,16 @@ namespace OpenSim.Region.Framework.Scenes
2458 if (!UUID.TryParse(sound, out soundID)) 2462 if (!UUID.TryParse(sound, out soundID))
2459 { 2463 {
2460 // search sound file from inventory 2464 // search sound file from inventory
2461 lock (TaskInventory) 2465 TaskInventory.LockItemsForRead(true);
2466 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2462 { 2467 {
2463 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2468 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2464 { 2469 {
2465 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2470 soundID = item.Value.ItemID;
2466 { 2471 break;
2467 soundID = item.Value.ItemID;
2468 break;
2469 }
2470 } 2472 }
2471 } 2473 }
2474 TaskInventory.LockItemsForRead(false);
2472 } 2475 }
2473 2476
2474 if (soundID == UUID.Zero) 2477 if (soundID == UUID.Zero)
@@ -2684,6 +2687,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2687 SetText(text);
2685 } 2688 }
2686 2689
2690 public void StopLookAt()
2691 {
2692 m_parentGroup.stopLookAt();
2693
2694 m_parentGroup.ScheduleGroupForTerseUpdate();
2695 }
2696
2687 public void StopMoveToTarget() 2697 public void StopMoveToTarget()
2688 { 2698 {
2689 m_parentGroup.stopMoveToTarget(); 2699 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 7a0d7b7..eca8588 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </value> 80 /// </value>
81 protected internal TaskInventoryDictionary Items 81 protected internal TaskInventoryDictionary Items
82 { 82 {
83 get { return m_items; } 83 get {
84 return m_items;
85 }
84 set 86 set
85 { 87 {
86 m_items = value; 88 m_items = value;
@@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes
116 /// <param name="linkNum">Link number for the part</param> 118 /// <param name="linkNum">Link number for the part</param>
117 public void ResetInventoryIDs() 119 public void ResetInventoryIDs()
118 { 120 {
119 lock (Items) 121 m_items.LockItemsForWrite(true);
122
123 if (0 == Items.Count)
120 { 124 {
121 if (0 == Items.Count) 125 m_items.LockItemsForWrite(false);
122 return; 126 return;
127 }
123 128
124 HasInventoryChanged = true; 129 HasInventoryChanged = true;
125 m_part.ParentGroup.HasGroupChanged = true; 130 m_part.ParentGroup.HasGroupChanged = true;
126 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 131 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
127 Items.Clear(); 132 Items.Clear();
128 133
129 foreach (TaskInventoryItem item in items) 134 foreach (TaskInventoryItem item in items)
130 { 135 {
131 item.ResetIDs(m_part.UUID); 136 item.ResetIDs(m_part.UUID);
132 Items.Add(item.ItemID, item); 137 Items.Add(item.ItemID, item);
133 }
134 } 138 }
139 m_items.LockItemsForWrite(false);
135 } 140 }
136 141
137 /// <summary> 142 /// <summary>
@@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes
140 /// <param name="ownerId"></param> 145 /// <param name="ownerId"></param>
141 public void ChangeInventoryOwner(UUID ownerId) 146 public void ChangeInventoryOwner(UUID ownerId)
142 { 147 {
143 lock (Items) 148 m_items.LockItemsForWrite(true);
149 if (0 == Items.Count)
144 { 150 {
145 if (0 == Items.Count) 151 m_items.LockItemsForWrite(false);
146 { 152 return;
147 return; 153 }
148 }
149 154
150 HasInventoryChanged = true; 155 HasInventoryChanged = true;
151 m_part.ParentGroup.HasGroupChanged = true; 156 m_part.ParentGroup.HasGroupChanged = true;
152 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
153 foreach (TaskInventoryItem item in items) 158 foreach (TaskInventoryItem item in items)
159 {
160 if (ownerId != item.OwnerID)
154 { 161 {
155 if (ownerId != item.OwnerID) 162 item.LastOwnerID = item.OwnerID;
156 { 163 item.OwnerID = ownerId;
157 item.LastOwnerID = item.OwnerID;
158 item.OwnerID = ownerId;
159 }
160 } 164 }
161 } 165 }
166 m_items.LockItemsForWrite(false);
162 } 167 }
163 168
164 /// <summary> 169 /// <summary>
@@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes
167 /// <param name="groupID"></param> 172 /// <param name="groupID"></param>
168 public void ChangeInventoryGroup(UUID groupID) 173 public void ChangeInventoryGroup(UUID groupID)
169 { 174 {
170 lock (Items) 175 m_items.LockItemsForWrite(true);
176 if (0 == Items.Count)
171 { 177 {
172 if (0 == Items.Count) 178 m_items.LockItemsForWrite(false);
173 { 179 return;
174 return; 180 }
175 }
176 181
177 HasInventoryChanged = true; 182 HasInventoryChanged = true;
178 m_part.ParentGroup.HasGroupChanged = true; 183 m_part.ParentGroup.HasGroupChanged = true;
179 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 184 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
180 foreach (TaskInventoryItem item in items) 185 foreach (TaskInventoryItem item in items)
186 {
187 if (groupID != item.GroupID)
181 { 188 {
182 if (groupID != item.GroupID) 189 item.GroupID = groupID;
183 {
184 item.GroupID = groupID;
185 }
186 } 190 }
187 } 191 }
192 m_items.LockItemsForWrite(false);
188 } 193 }
189 194
190 /// <summary> 195 /// <summary>
@@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes
192 /// </summary> 197 /// </summary>
193 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 198 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
194 { 199 {
195 lock (m_items) 200 Items.LockItemsForRead(true);
201 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
202 Items.LockItemsForRead(false);
203 foreach (TaskInventoryItem item in items)
196 { 204 {
197 foreach (TaskInventoryItem item in Items.Values) 205 if ((int)InventoryType.LSL == item.InvType)
198 { 206 {
199 if ((int)InventoryType.LSL == item.InvType) 207 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
200 {
201 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 }
203 } 208 }
204 } 209 }
205 } 210 }
@@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes
209 /// </summary> 214 /// </summary>
210 public void RemoveScriptInstances() 215 public void RemoveScriptInstances()
211 { 216 {
212 lock (Items) 217 Items.LockItemsForRead(true);
218 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
219 Items.LockItemsForRead(false);
220
221 foreach (TaskInventoryItem item in items)
213 { 222 {
214 foreach (TaskInventoryItem item in Items.Values) 223 if ((int)InventoryType.LSL == item.InvType)
215 { 224 {
216 if ((int)InventoryType.LSL == item.InvType) 225 RemoveScriptInstance(item.ItemID);
217 { 226 m_part.RemoveScriptEvents(item.ItemID);
218 RemoveScriptInstance(item.ItemID);
219 m_part.RemoveScriptEvents(item.ItemID);
220 }
221 } 227 }
222 } 228 }
229
230
223 } 231 }
224 232
225 /// <summary> 233 /// <summary>
@@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes
244 if (stateSource == 1 && // Prim crossing 252 if (stateSource == 1 && // Prim crossing
245 m_part.ParentGroup.Scene.m_trustBinaries) 253 m_part.ParentGroup.Scene.m_trustBinaries)
246 { 254 {
255 m_items.LockItemsForWrite(true);
247 m_items[item.ItemID].PermsMask = 0; 256 m_items[item.ItemID].PermsMask = 0;
248 m_items[item.ItemID].PermsGranter = UUID.Zero; 257 m_items[item.ItemID].PermsGranter = UUID.Zero;
258 m_items.LockItemsForWrite(false);
249 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 259 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
250 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 260 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
251 m_part.ParentGroup.AddActiveScriptCount(1); 261 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -266,8 +276,10 @@ namespace OpenSim.Region.Framework.Scenes
266 { 276 {
267 if (m_part.ParentGroup.m_savedScriptState != null) 277 if (m_part.ParentGroup.m_savedScriptState != null)
268 RestoreSavedScriptState(item.OldItemID, item.ItemID); 278 RestoreSavedScriptState(item.OldItemID, item.ItemID);
279 m_items.LockItemsForWrite(true);
269 m_items[item.ItemID].PermsMask = 0; 280 m_items[item.ItemID].PermsMask = 0;
270 m_items[item.ItemID].PermsGranter = UUID.Zero; 281 m_items[item.ItemID].PermsGranter = UUID.Zero;
282 m_items.LockItemsForWrite(false);
271 string script = Utils.BytesToString(asset.Data); 283 string script = Utils.BytesToString(asset.Data);
272 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 284 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
273 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 285 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -302,20 +314,22 @@ namespace OpenSim.Region.Framework.Scenes
302 /// </param> 314 /// </param>
303 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 315 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
304 { 316 {
305 lock (m_items) 317 m_items.LockItemsForRead(true);
318 if (m_items.ContainsKey(itemId))
306 { 319 {
307 if (m_items.ContainsKey(itemId)) 320 TaskInventoryItem item = m_items[itemId];
308 { 321 m_items.LockItemsForRead(false);
309 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 322 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
310 }
311 else
312 {
313 m_log.ErrorFormat(
314 "[PRIM INVENTORY]: " +
315 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
316 itemId, m_part.Name, m_part.UUID);
317 }
318 } 323 }
324 else
325 {
326 m_items.LockItemsForRead(false);
327 m_log.ErrorFormat(
328 "[PRIM INVENTORY]: " +
329 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
330 itemId, m_part.Name, m_part.UUID);
331 }
332
319 } 333 }
320 334
321 /// <summary> 335 /// <summary>
@@ -346,11 +360,16 @@ namespace OpenSim.Region.Framework.Scenes
346 /// <returns></returns> 360 /// <returns></returns>
347 private bool InventoryContainsName(string name) 361 private bool InventoryContainsName(string name)
348 { 362 {
349 foreach (TaskInventoryItem item in Items.Values) 363 m_items.LockItemsForRead(true);
364 foreach (TaskInventoryItem item in m_items.Values)
350 { 365 {
351 if (item.Name == name) 366 if (item.Name == name)
367 {
368 m_items.LockItemsForRead(false);
352 return true; 369 return true;
370 }
353 } 371 }
372 m_items.LockItemsForRead(false);
354 return false; 373 return false;
355 } 374 }
356 375
@@ -392,7 +411,9 @@ namespace OpenSim.Region.Framework.Scenes
392 /// <param name="item"></param> 411 /// <param name="item"></param>
393 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 412 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
394 { 413 {
414 m_items.LockItemsForRead(true);
395 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 415 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
416 m_items.LockItemsForRead(false);
396 foreach (TaskInventoryItem i in il) 417 foreach (TaskInventoryItem i in il)
397 { 418 {
398 if (i.Name == item.Name) 419 if (i.Name == item.Name)
@@ -429,15 +450,14 @@ namespace OpenSim.Region.Framework.Scenes
429 item.ParentPartID = m_part.UUID; 450 item.ParentPartID = m_part.UUID;
430 item.Name = name; 451 item.Name = name;
431 452
432 lock (m_items) 453 m_items.LockItemsForWrite(true);
433 { 454 m_items.Add(item.ItemID, item);
434 m_items.Add(item.ItemID, item); 455 m_items.LockItemsForWrite(false);
435
436 if (allowedDrop) 456 if (allowedDrop)
437 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 457 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
438 else 458 else
439 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 459 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
440 } 460
441 461
442 m_inventorySerial++; 462 m_inventorySerial++;
443 //m_inventorySerial += 2; 463 //m_inventorySerial += 2;
@@ -454,14 +474,13 @@ namespace OpenSim.Region.Framework.Scenes
454 /// <param name="items"></param> 474 /// <param name="items"></param>
455 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 475 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
456 { 476 {
457 lock (m_items) 477 m_items.LockItemsForWrite(true);
478 foreach (TaskInventoryItem item in items)
458 { 479 {
459 foreach (TaskInventoryItem item in items) 480 m_items.Add(item.ItemID, item);
460 { 481 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
461 m_items.Add(item.ItemID, item);
462 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
463 }
464 } 482 }
483 m_items.LockItemsForWrite(false);
465 484
466 m_inventorySerial++; 485 m_inventorySerial++;
467 } 486 }
@@ -474,8 +493,9 @@ namespace OpenSim.Region.Framework.Scenes
474 public TaskInventoryItem GetInventoryItem(UUID itemId) 493 public TaskInventoryItem GetInventoryItem(UUID itemId)
475 { 494 {
476 TaskInventoryItem item; 495 TaskInventoryItem item;
496 m_items.LockItemsForRead(true);
477 m_items.TryGetValue(itemId, out item); 497 m_items.TryGetValue(itemId, out item);
478 498 m_items.LockItemsForRead(false);
479 return item; 499 return item;
480 } 500 }
481 501
@@ -487,45 +507,45 @@ namespace OpenSim.Region.Framework.Scenes
487 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 507 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
488 public bool UpdateInventoryItem(TaskInventoryItem item) 508 public bool UpdateInventoryItem(TaskInventoryItem item)
489 { 509 {
490 lock (m_items) 510 m_items.LockItemsForWrite(true);
511
512 if (m_items.ContainsKey(item.ItemID))
491 { 513 {
492 if (m_items.ContainsKey(item.ItemID)) 514 item.ParentID = m_part.UUID;
515 item.ParentPartID = m_part.UUID;
516 item.Flags = m_items[item.ItemID].Flags;
517 if (item.AssetID == UUID.Zero)
493 { 518 {
494 item.ParentID = m_part.UUID; 519 item.AssetID = m_items[item.ItemID].AssetID;
495 item.ParentPartID = m_part.UUID; 520 }
496 item.Flags = m_items[item.ItemID].Flags; 521 else if ((InventoryType)item.Type == InventoryType.Notecard)
497 if (item.AssetID == UUID.Zero) 522 {
498 { 523 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
499 item.AssetID = m_items[item.ItemID].AssetID;
500 }
501 else if ((InventoryType)item.Type == InventoryType.Notecard)
502 {
503 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
504 524
505 if (presence != null) 525 if (presence != null)
506 { 526 {
507 presence.ControllingClient.SendAgentAlertMessage( 527 presence.ControllingClient.SendAgentAlertMessage(
508 "Notecard saved", false); 528 "Notecard saved", false);
509 }
510 } 529 }
530 }
511 531
512 m_items[item.ItemID] = item; 532 m_items[item.ItemID] = item;
513 m_inventorySerial++; 533 m_inventorySerial++;
514 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 534 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
515
516 HasInventoryChanged = true;
517 m_part.ParentGroup.HasGroupChanged = true;
518 535
519 return true; 536 HasInventoryChanged = true;
520 } 537 m_part.ParentGroup.HasGroupChanged = true;
521 else 538 m_items.LockItemsForWrite(false);
522 { 539 return true;
523 m_log.ErrorFormat( 540 }
524 "[PRIM INVENTORY]: " + 541 else
525 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", 542 {
526 item.ItemID, m_part.Name, m_part.UUID); 543 m_log.ErrorFormat(
527 } 544 "[PRIM INVENTORY]: " +
545 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
546 item.ItemID, m_part.Name, m_part.UUID);
528 } 547 }
548 m_items.LockItemsForWrite(false);
529 549
530 return false; 550 return false;
531 } 551 }
@@ -538,51 +558,54 @@ namespace OpenSim.Region.Framework.Scenes
538 /// in this prim's inventory.</returns> 558 /// in this prim's inventory.</returns>
539 public int RemoveInventoryItem(UUID itemID) 559 public int RemoveInventoryItem(UUID itemID)
540 { 560 {
541 lock (m_items) 561 m_items.LockItemsForRead(true);
562
563 if (m_items.ContainsKey(itemID))
542 { 564 {
543 if (m_items.ContainsKey(itemID)) 565 int type = m_items[itemID].InvType;
566 m_items.LockItemsForRead(false);
567 if (type == 10) // Script
544 { 568 {
545 int type = m_items[itemID].InvType; 569 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
546 if (type == 10) // Script 570 }
547 { 571 m_items.LockItemsForWrite(true);
548 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 572 m_items.Remove(itemID);
549 } 573 m_items.LockItemsForWrite(false);
550 m_items.Remove(itemID); 574 m_inventorySerial++;
551 m_inventorySerial++; 575 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
552 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
553
554 HasInventoryChanged = true;
555 m_part.ParentGroup.HasGroupChanged = true;
556 576
557 int scriptcount = 0; 577 HasInventoryChanged = true;
558 lock (m_items) 578 m_part.ParentGroup.HasGroupChanged = true;
559 {
560 foreach (TaskInventoryItem item in m_items.Values)
561 {
562 if (item.Type == 10)
563 {
564 scriptcount++;
565 }
566 }
567 }
568 579
569 if (scriptcount <= 0) 580 int scriptcount = 0;
581 m_items.LockItemsForRead(true);
582 foreach (TaskInventoryItem item in m_items.Values)
583 {
584 if (item.Type == 10)
570 { 585 {
571 m_part.RemFlag(PrimFlags.Scripted); 586 scriptcount++;
572 } 587 }
573
574 m_part.ScheduleFullUpdate();
575
576 return type;
577 } 588 }
578 else 589 m_items.LockItemsForRead(false);
590
591
592 if (scriptcount <= 0)
579 { 593 {
580 m_log.ErrorFormat( 594 m_part.RemFlag(PrimFlags.Scripted);
581 "[PRIM INVENTORY]: " +
582 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
583 itemID, m_part.Name, m_part.UUID);
584 } 595 }
596
597 m_part.ScheduleFullUpdate();
598
599 return type;
600 }
601 else
602 {
603 m_log.ErrorFormat(
604 "[PRIM INVENTORY]: " +
605 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
606 itemID, m_part.Name, m_part.UUID);
585 } 607 }
608 m_items.LockItemsForWrite(false);
586 609
587 return -1; 610 return -1;
588 } 611 }
@@ -635,52 +658,53 @@ namespace OpenSim.Region.Framework.Scenes
635 // isn't available (such as drag from prim inventory to agent inventory) 658 // isn't available (such as drag from prim inventory to agent inventory)
636 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 659 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
637 660
638 lock (m_items) 661 m_items.LockItemsForRead(true);
662
663 foreach (TaskInventoryItem item in m_items.Values)
639 { 664 {
640 foreach (TaskInventoryItem item in m_items.Values) 665 UUID ownerID = item.OwnerID;
641 { 666 uint everyoneMask = 0;
642 UUID ownerID = item.OwnerID; 667 uint baseMask = item.BasePermissions;
643 uint everyoneMask = 0; 668 uint ownerMask = item.CurrentPermissions;
644 uint baseMask = item.BasePermissions;
645 uint ownerMask = item.CurrentPermissions;
646 669
647 invString.AddItemStart(); 670 invString.AddItemStart();
648 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 671 invString.AddNameValueLine("item_id", item.ItemID.ToString());
649 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 672 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
650 673
651 invString.AddPermissionsStart(); 674 invString.AddPermissionsStart();
652 675
653 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 676 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
654 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 677 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
655 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 678 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
656 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 679 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
657 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 680 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
658 681
659 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 682 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
660 invString.AddNameValueLine("owner_id", ownerID.ToString()); 683 invString.AddNameValueLine("owner_id", ownerID.ToString());
661 684
662 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 685 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
663 686
664 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 687 invString.AddNameValueLine("group_id", item.GroupID.ToString());
665 invString.AddSectionEnd(); 688 invString.AddSectionEnd();
666 689
667 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 690 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
668 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 691 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
669 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 692 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
670 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 693 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
671 694
672 invString.AddSaleStart(); 695 invString.AddSaleStart();
673 invString.AddNameValueLine("sale_type", "not"); 696 invString.AddNameValueLine("sale_type", "not");
674 invString.AddNameValueLine("sale_price", "0"); 697 invString.AddNameValueLine("sale_price", "0");
675 invString.AddSectionEnd(); 698 invString.AddSectionEnd();
676 699
677 invString.AddNameValueLine("name", item.Name + "|"); 700 invString.AddNameValueLine("name", item.Name + "|");
678 invString.AddNameValueLine("desc", item.Description + "|"); 701 invString.AddNameValueLine("desc", item.Description + "|");
679 702
680 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 703 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
681 invString.AddSectionEnd(); 704 invString.AddSectionEnd();
682 }
683 } 705 }
706 int count = m_items.Count;
707 m_items.LockItemsForRead(false);
684 708
685 fileData = Utils.StringToBytes(invString.BuildString); 709 fileData = Utils.StringToBytes(invString.BuildString);
686 710
@@ -701,10 +725,9 @@ namespace OpenSim.Region.Framework.Scenes
701 { 725 {
702 if (HasInventoryChanged) 726 if (HasInventoryChanged)
703 { 727 {
704 lock (Items) 728 Items.LockItemsForRead(true);
705 { 729 datastore.StorePrimInventory(m_part.UUID, Items.Values);
706 datastore.StorePrimInventory(m_part.UUID, Items.Values); 730 Items.LockItemsForRead(false);
707 }
708 731
709 HasInventoryChanged = false; 732 HasInventoryChanged = false;
710 } 733 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5604e3d..a1bb244 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,8 @@ 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 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 94
94 public UUID currentParcelUUID = UUID.Zero; 95 public UUID currentParcelUUID = UUID.Zero;
95 96
@@ -113,7 +114,8 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 114 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 115 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 116 public Vector4 CollisionPlane = Vector4.UnitW;
116 117
118 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
117 private Vector3 m_lastPosition; 119 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 120 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 121 private Vector3 m_lastVelocity;
@@ -144,7 +146,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 146 private int m_perfMonMS;
145 147
146 private bool m_setAlwaysRun; 148 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 149 private bool m_forceFly;
149 private bool m_flyDisabled; 150 private bool m_flyDisabled;
150 151
@@ -168,7 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 169 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 170 protected ulong crossingFromRegion;
170 171
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 172 private readonly Vector3[] Dir_Vectors = new Vector3[11];
173 private bool m_isNudging = false;
172 174
173 // Position of agent's camera in world (region cordinates) 175 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 176 protected Vector3 m_CameraCenter;
@@ -232,6 +234,10 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 234 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
239 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
240 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
235 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 241 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 242 }
237 243
@@ -716,21 +722,47 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 722 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 723 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 724 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 725 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
726 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
727 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
728 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
729 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 730 }
721 731
722 private Vector3[] GetWalkDirectionVectors() 732 private Vector3[] GetWalkDirectionVectors()
723 { 733 {
724 Vector3[] vector = new Vector3[6]; 734 Vector3[] vector = new Vector3[11];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 735 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 736 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 737 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 738 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 739 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 740 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 741 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
742 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
743 vector[8] = Vector3.UnitY; //LEFT_NUDGE
744 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
745 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
732 return vector; 746 return vector;
733 } 747 }
748
749 private bool[] GetDirectionIsNudge()
750 {
751 bool[] isNudge = new bool[11];
752 isNudge[0] = false; //FORWARD
753 isNudge[1] = false; //BACK
754 isNudge[2] = false; //LEFT
755 isNudge[3] = false; //RIGHT
756 isNudge[4] = false; //UP
757 isNudge[5] = false; //DOWN
758 isNudge[6] = true; //FORWARD_NUDGE
759 isNudge[7] = true; //BACK_NUDGE
760 isNudge[8] = true; //LEFT_NUDGE
761 isNudge[9] = true; //RIGHT_NUDGE
762 isNudge[10] = true; //DOWN_Nudge
763 return isNudge;
764 }
765
734 766
735 #endregion 767 #endregion
736 768
@@ -1147,7 +1179,6 @@ namespace OpenSim.Region.Framework.Scenes
1147 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1179 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
1148 // return; 1180 // return;
1149 //} 1181 //}
1150
1151 m_perfMonMS = Environment.TickCount; 1182 m_perfMonMS = Environment.TickCount;
1152 1183
1153 ++m_movementUpdateCount; 1184 ++m_movementUpdateCount;
@@ -1229,7 +1260,6 @@ namespace OpenSim.Region.Framework.Scenes
1229 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1260 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1261 }
1231 } 1262 }
1232
1233 lock (scriptedcontrols) 1263 lock (scriptedcontrols)
1234 { 1264 {
1235 if (scriptedcontrols.Count > 0) 1265 if (scriptedcontrols.Count > 0)
@@ -1261,7 +1291,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1291 {
1262 return; 1292 return;
1263 } 1293 }
1264
1265 if (m_allowMovement) 1294 if (m_allowMovement)
1266 { 1295 {
1267 int i = 0; 1296 int i = 0;
@@ -1289,6 +1318,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1318 update_rotation = true;
1290 } 1319 }
1291 1320
1321 //guilty until proven innocent..
1322 bool Nudging = true;
1323 //Basically, if there is at least one non-nudge control then we don't need
1324 //to worry about stopping the avatar
1325
1292 if (m_parentID == 0) 1326 if (m_parentID == 0)
1293 { 1327 {
1294 bool bAllowUpdateMoveToPosition = false; 1328 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1337,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1337 else
1304 dirVectors = Dir_Vectors; 1338 dirVectors = Dir_Vectors;
1305 1339
1340 bool[] isNudge = GetDirectionIsNudge();
1341
1342
1343
1344
1345
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1346 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1347 {
1308 if (((uint)flags & (uint)DCF) != 0) 1348 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1352,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1352 try
1313 { 1353 {
1314 agent_control_v3 += dirVectors[i]; 1354 agent_control_v3 += dirVectors[i];
1355 if (isNudge[i] == false)
1356 {
1357 Nudging = false;
1358 }
1315 } 1359 }
1316 catch (IndexOutOfRangeException) 1360 catch (IndexOutOfRangeException)
1317 { 1361 {
@@ -1373,6 +1417,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1417 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1418 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1419 LocalVectorToTarget2D.Normalize();
1420
1421 //We're not nudging
1422 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1423 agent_control_v3 += LocalVectorToTarget2D;
1377 1424
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1425 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1502,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1502 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1503 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1504
1458 AddNewMovement(agent_control_v3, q); 1505 AddNewMovement(agent_control_v3, q, Nudging);
1459 1506
1460 if (update_movementflag) 1507 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1508 Animator.UpdateMovementAnimations();
@@ -1538,7 +1585,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1585 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1586 SendFullUpdateToAllClients();
1540 1587
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1588 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1589 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1590 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1591 m_requestedSitTargetUUID = UUID.Zero;
@@ -1576,21 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes
1576 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1623 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1577 if (part != null) 1624 if (part != null)
1578 { 1625 {
1626 part.TaskInventory.LockItemsForRead(true);
1579 TaskInventoryDictionary taskIDict = part.TaskInventory; 1627 TaskInventoryDictionary taskIDict = part.TaskInventory;
1580 if (taskIDict != null) 1628 if (taskIDict != null)
1581 { 1629 {
1582 lock (taskIDict) 1630 foreach (UUID taskID in taskIDict.Keys)
1583 { 1631 {
1584 foreach (UUID taskID in taskIDict.Keys) 1632 UnRegisterControlEventsToScript(LocalId, taskID);
1585 { 1633 taskIDict[taskID].PermsMask &= ~(
1586 UnRegisterControlEventsToScript(LocalId, taskID); 1634 2048 | //PERMISSION_CONTROL_CAMERA
1587 taskIDict[taskID].PermsMask &= ~( 1635 4); // PERMISSION_TAKE_CONTROLS
1588 2048 | //PERMISSION_CONTROL_CAMERA
1589 4); // PERMISSION_TAKE_CONTROLS
1590 }
1591 } 1636 }
1592
1593 } 1637 }
1638 part.TaskInventory.LockItemsForRead(false);
1594 // Reset sit target. 1639 // Reset sit target.
1595 if (part.GetAvatarOnSitTarget() == UUID) 1640 if (part.GetAvatarOnSitTarget() == UUID)
1596 part.SetAvatarOnSitTarget(UUID.Zero); 1641 part.SetAvatarOnSitTarget(UUID.Zero);
@@ -1651,7 +1696,7 @@ namespace OpenSim.Region.Framework.Scenes
1651 bool SitTargetisSet = 1696 bool SitTargetisSet =
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && 1697 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); 1698 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654 1699 // this test is probably failing
1655 if (SitTargetisSet && SitTargetUnOccupied) 1700 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1701 {
1657 //switch the target to this prim 1702 //switch the target to this prim
@@ -1678,26 +1723,37 @@ namespace OpenSim.Region.Framework.Scenes
1678 { 1723 {
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1724 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1680 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1725 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1726
1727 // part is the prim to sit on
1728 // offset is the vector distance from that prim center to the click-spot
1729 // UUID is the UUID of the Avatar doing the clicking
1730
1731 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1732
1682 // Is a sit target available? 1733 // Is a sit target available?
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1734 Vector3 avSitOffSet = part.SitTargetPosition;
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1735 Quaternion avSitOrientation = part.SitTargetOrientation;
1685 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1736 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1686 1737
1687 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1738 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1688 bool SitTargetisSet = 1739// bool SitTargetisSet =
1689 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && 1740// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f &&
1690 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); 1741// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f));
1691 1742
1743 bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation));
1744
1745//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1746// " TargSet=" + SitTargetisSet);
1747
1692 if (SitTargetisSet && SitTargetUnOccupied) 1748 if (SitTargetisSet && SitTargetUnOccupied)
1693 { 1749 {
1694 part.SetAvatarOnSitTarget(UUID); 1750 part.SetAvatarOnSitTarget(UUID);
1695 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1751 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1696 sitOrientation = avSitOrientation; 1752 sitOrientation = avSitOrientation;
1697 autopilot = false; 1753 autopilot = false; // Jump direct to scripted llSitPos()
1698 } 1754 }
1699 1755
1700 pos = part.AbsolutePosition + offset; 1756 pos = part.AbsolutePosition + offset; // Region position where clicked
1701 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1757 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1702 //{ 1758 //{
1703 // offset = pos; 1759 // offset = pos;
@@ -1710,17 +1766,17 @@ namespace OpenSim.Region.Framework.Scenes
1710 m_sitAvatarHeight = m_physicsActor.Size.Z; 1766 m_sitAvatarHeight = m_physicsActor.Size.Z;
1711 1767
1712 if (autopilot) 1768 if (autopilot)
1713 { 1769 { // its not a scripted sit
1714 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1770 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1715 { 1771 {
1716 autopilot = false; 1772 autopilot = false; // close enough
1717 1773
1718 RemoveFromPhysicalScene(); 1774 RemoveFromPhysicalScene();
1719 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1775 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim
1720 } 1776 } // else the autopilot will get us close
1721 } 1777 }
1722 else 1778 else
1723 { 1779 { // its a scripted sit
1724 RemoveFromPhysicalScene(); 1780 RemoveFromPhysicalScene();
1725 } 1781 }
1726 } 1782 }
@@ -1823,26 +1879,41 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1879 {
1824 if (part.GetAvatarOnSitTarget() == UUID) 1880 if (part.GetAvatarOnSitTarget() == UUID)
1825 { 1881 {
1882 // Scripted sit
1826 Vector3 sitTargetPos = part.SitTargetPosition; 1883 Vector3 sitTargetPos = part.SitTargetPosition;
1827 Quaternion sitTargetOrient = part.SitTargetOrientation; 1884 Quaternion sitTargetOrient = part.SitTargetOrientation;
1828
1829 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1830 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1831
1832 //Quaternion result = (sitTargetOrient * vq) * nq;
1833
1834 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1885 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1835 m_pos += SIT_TARGET_ADJUSTMENT; 1886 m_pos += SIT_TARGET_ADJUSTMENT;
1836 m_bodyRot = sitTargetOrient; 1887 m_bodyRot = sitTargetOrient;
1837 //Rotation = sitTargetOrient;
1838 m_parentPosition = part.AbsolutePosition; 1888 m_parentPosition = part.AbsolutePosition;
1839
1840 //SendTerseUpdateToAllClients();
1841 } 1889 }
1842 else 1890 else
1843 { 1891 {
1844 m_pos -= part.AbsolutePosition; 1892 // Non-scripted sit by Kitto Flora 21Nov09
1893 // Calculate angle of line from prim to Av
1894 float y_diff = (m_avInitialPos.Y - part.AbsolutePosition.Y);
1895 float x_diff = ( m_avInitialPos.X - part.AbsolutePosition.X);
1896 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1897 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1898 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1899 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1900 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1901 // Av sits at world euler <0,0, z>, translated by part rotation
1902 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1903 m_pos = new Vector3(0f, 0f, 0.05f) +
1904 (new Vector3(0.0f, 0f, 0.625f) * partIRot) +
1905 (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); // sit at center of prim
1845 m_parentPosition = part.AbsolutePosition; 1906 m_parentPosition = part.AbsolutePosition;
1907 //Set up raytrace to find top surface of prim
1908 Vector3 size = part.Scale;
1909 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1910 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1911 Vector3 down = new Vector3(0f, 0f, -1f);
1912 m_scene.PhysicsScene.RaycastWorld(
1913 start, // Vector3 position,
1914 down, // Vector3 direction,
1915 mag, // float length,
1916 SitAltitudeCallback); // retMethod
1846 } 1917 }
1847 } 1918 }
1848 else 1919 else
@@ -1857,11 +1928,22 @@ namespace OpenSim.Region.Framework.Scenes
1857 1928
1858 Animator.TrySetMovementAnimation(sitAnimation); 1929 Animator.TrySetMovementAnimation(sitAnimation);
1859 SendFullUpdateToAllClients(); 1930 SendFullUpdateToAllClients();
1860 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1861 // So we're also sending a terse update (which has avatar rotation)
1862 // [Update] We do now.
1863 //SendTerseUpdateToAllClients();
1864 } 1931 }
1932
1933 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1934 {
1935// Console.WriteLine("[RAYCASTRESULT]: Hit={0}, Point={1}, ID={2}, Dist={3}", hitYN, collisionPoint, localid, distance);
1936 if(hitYN)
1937 {
1938 // m_pos = Av offset from prim center to make look like on center
1939 // m_parentPosition = Actual center pos of prim
1940 // collisionPoint = spot on prim where we want to sit
1941 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1942 Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset);
1943 m_pos += offset;
1944// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit);
1945 }
1946 }
1865 1947
1866 /// <summary> 1948 /// <summary>
1867 /// Event handler for the 'Always run' setting on the client 1949 /// Event handler for the 'Always run' setting on the client
@@ -1891,7 +1973,7 @@ namespace OpenSim.Region.Framework.Scenes
1891 /// </summary> 1973 /// </summary>
1892 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 1974 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1893 /// <param name="rotation">The direction in which this avatar should now face. 1975 /// <param name="rotation">The direction in which this avatar should now face.
1894 public void AddNewMovement(Vector3 vec, Quaternion rotation) 1976 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1895 { 1977 {
1896 if (m_isChildAgent) 1978 if (m_isChildAgent)
1897 { 1979 {
@@ -1965,7 +2047,7 @@ namespace OpenSim.Region.Framework.Scenes
1965 2047
1966 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2048 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1967 m_forceToApply = direc; 2049 m_forceToApply = direc;
1968 2050 m_isNudging = Nudging;
1969 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2051 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
1970 } 2052 }
1971 2053
@@ -1980,7 +2062,7 @@ namespace OpenSim.Region.Framework.Scenes
1980 const float POSITION_TOLERANCE = 0.05f; 2062 const float POSITION_TOLERANCE = 0.05f;
1981 //const int TIME_MS_TOLERANCE = 3000; 2063 //const int TIME_MS_TOLERANCE = 3000;
1982 2064
1983 SendPrimUpdates(); 2065
1984 2066
1985 if (m_newCoarseLocations) 2067 if (m_newCoarseLocations)
1986 { 2068 {
@@ -2016,6 +2098,9 @@ namespace OpenSim.Region.Framework.Scenes
2016 CheckForBorderCrossing(); 2098 CheckForBorderCrossing();
2017 CheckForSignificantMovement(); // sends update to the modules. 2099 CheckForSignificantMovement(); // sends update to the modules.
2018 } 2100 }
2101
2102 //Sending prim updates AFTER the avatar terse updates are sent
2103 SendPrimUpdates();
2019 } 2104 }
2020 2105
2021 #endregion 2106 #endregion
@@ -2869,14 +2954,24 @@ namespace OpenSim.Region.Framework.Scenes
2869 { 2954 {
2870 if (m_forceToApply.HasValue) 2955 if (m_forceToApply.HasValue)
2871 { 2956 {
2872 Vector3 force = m_forceToApply.Value;
2873 2957
2958 Vector3 force = m_forceToApply.Value;
2874 m_updateflag = true; 2959 m_updateflag = true;
2875// movementvector = force;
2876 Velocity = force; 2960 Velocity = force;
2877 2961
2878 m_forceToApply = null; 2962 m_forceToApply = null;
2879 } 2963 }
2964 else
2965 {
2966 if (m_isNudging)
2967 {
2968 Vector3 force = Vector3.Zero;
2969
2970 m_updateflag = true;
2971 Velocity = force;
2972 m_isNudging = false;
2973 }
2974 }
2880 } 2975 }
2881 2976
2882 public override void SetText(string text, Vector3 color, double alpha) 2977 public override void SetText(string text, Vector3 color, double alpha)
@@ -3585,4 +3680,4 @@ namespace OpenSim.Region.Framework.Scenes
3585 } 3680 }
3586 } 3681 }
3587 } 3682 }
3588} \ No newline at end of file 3683}