aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs29
-rw-r--r--OpenSim/Framework/LocklessQueue.cs8
-rw-r--r--OpenSim/Framework/ThrottleOutPacketType.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs69
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs10
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISearchModule.cs2
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs207
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs14
11 files changed, 167 insertions, 216 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 3d80eb6..9f3844b 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -157,6 +157,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
157 availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove); 157 availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove);
158 availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); 158 availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
159 159
160 // Misc
161 availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
162
160 // Either enable full remote functionality or just selected features 163 // Either enable full remote functionality or just selected features
161 string enabledMethods = m_config.GetString("enabled_methods", "all"); 164 string enabledMethods = m_config.GetString("enabled_methods", "all");
162 165
@@ -1948,6 +1951,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1948 responseData["success"] = true; 1951 responseData["success"] = true;
1949 } 1952 }
1950 1953
1954 private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1955 {
1956 m_log.Info("[RADMIN]: Received Refresh Search Request");
1957
1958 Hashtable responseData = (Hashtable)response.Value;
1959 Hashtable requestData = (Hashtable)request.Params[0];
1960
1961 CheckRegionParams(requestData, responseData);
1962
1963 Scene scene = null;
1964 GetSceneFromRegionParams(requestData, responseData, out scene);
1965
1966 ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
1967 if (searchModule != null)
1968 {
1969 searchModule.Refresh();
1970 responseData["success"] = true;
1971 }
1972 else
1973 {
1974 responseData["success"] = false;
1975 }
1976
1977 m_log.Info("[RADMIN]: Refresh Search Request complete");
1978 }
1979
1951 /// <summary> 1980 /// <summary>
1952 /// Parse a float with the given parameter name from a request data hash table. 1981 /// Parse a float with the given parameter name from a request data hash table.
1953 /// </summary> 1982 /// </summary>
diff --git a/OpenSim/Framework/LocklessQueue.cs b/OpenSim/Framework/LocklessQueue.cs
index 84f887c..9bd9baf 100644
--- a/OpenSim/Framework/LocklessQueue.cs
+++ b/OpenSim/Framework/LocklessQueue.cs
@@ -29,7 +29,7 @@ using System.Threading;
29 29
30namespace OpenSim.Framework 30namespace OpenSim.Framework
31{ 31{
32 public sealed class LocklessQueue<T> 32 public class LocklessQueue<T>
33 { 33 {
34 private sealed class SingleLinkNode 34 private sealed class SingleLinkNode
35 { 35 {
@@ -41,7 +41,7 @@ namespace OpenSim.Framework
41 SingleLinkNode tail; 41 SingleLinkNode tail;
42 int count; 42 int count;
43 43
44 public int Count { get { return count; } } 44 public virtual int Count { get { return count; } }
45 45
46 public LocklessQueue() 46 public LocklessQueue()
47 { 47 {
@@ -76,7 +76,7 @@ namespace OpenSim.Framework
76 Interlocked.Increment(ref count); 76 Interlocked.Increment(ref count);
77 } 77 }
78 78
79 public bool Dequeue(out T item) 79 public virtual bool Dequeue(out T item)
80 { 80 {
81 item = default(T); 81 item = default(T);
82 SingleLinkNode oldHead = null; 82 SingleLinkNode oldHead = null;
@@ -136,4 +136,4 @@ namespace OpenSim.Framework
136 (object)Interlocked.CompareExchange<SingleLinkNode>(ref location, newValue, comparand); 136 (object)Interlocked.CompareExchange<SingleLinkNode>(ref location, newValue, comparand);
137 } 137 }
138 } 138 }
139} \ No newline at end of file 139}
diff --git a/OpenSim/Framework/ThrottleOutPacketType.cs b/OpenSim/Framework/ThrottleOutPacketType.cs
index d56231a..87899f0 100644
--- a/OpenSim/Framework/ThrottleOutPacketType.cs
+++ b/OpenSim/Framework/ThrottleOutPacketType.cs
@@ -47,9 +47,8 @@ namespace OpenSim.Framework
47 Texture = 5, 47 Texture = 5,
48 /// <summary>Non-texture assets</summary> 48 /// <summary>Non-texture assets</summary>
49 Asset = 6, 49 Asset = 6,
50 /// <summary>Avatar and primitive data</summary> 50
51 /// <remarks>This is a sub-category of Task</remarks> 51 HighPriority = 128,
52 State = 7,
53 } 52 }
54 53
55 [Flags] 54 [Flags]
@@ -61,6 +60,5 @@ namespace OpenSim.Framework
61 Task = 1 << 3, 60 Task = 1 << 3,
62 Texture = 1 << 4, 61 Texture = 1 << 4,
63 Asset = 1 << 5, 62 Asset = 1 << 5,
64 State = 1 << 6,
65 } 63 }
66} 64}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 908f628..6ec1115 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -501,7 +501,8 @@ namespace OpenSim.Region.ClientStack.Linden
501 ScenePresence p; 501 ScenePresence p;
502 if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore. 502 if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore.
503 { 503 {
504 AlterThrottle(UserSetThrottle, p); 504// AlterThrottle(UserSetThrottle, p);
505 UpdateThrottle(UserSetThrottle, p);
505 } 506 }
506 } 507 }
507 } 508 }
@@ -546,7 +547,12 @@ namespace OpenSim.Region.ClientStack.Linden
546 // Client set throttle ! 547 // Client set throttle !
547 UserSetThrottle = pimagethrottle; 548 UserSetThrottle = pimagethrottle;
548 CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon); 549 CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
549 UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon)); 550// UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
551
552 float udp = 1.0f - CapThrottleDistributon;
553 if(udp < 0.5f)
554 udp = 0.5f;
555 UDPSetThrottle = (int) ((float)pimagethrottle * udp);
550 if (CapSetThrottle < 4068) 556 if (CapSetThrottle < 4068)
551 CapSetThrottle = 4068; // at least two discovery mesh 557 CapSetThrottle = 4068; // at least two discovery mesh
552 p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle); 558 p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 0a865ab..9550b5a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1607,7 +1607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1607 1607
1608 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) 1608 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
1609 { 1609 {
1610 OutPacket(kill, ThrottleOutPacketType.State); 1610 OutPacket(kill, ThrottleOutPacketType.Task);
1611 } 1611 }
1612 else 1612 else
1613 { 1613 {
@@ -2788,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2788 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2788 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2789 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2789 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2790 Transfer.Header.Zerocoded = true; 2790 Transfer.Header.Zerocoded = true;
2791 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); 2791 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2792 2792
2793 if (req.NumPackets == 1) 2793 if (req.NumPackets == 1)
2794 { 2794 {
@@ -2799,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2799 TransferPacket.TransferData.Data = req.AssetInf.Data; 2799 TransferPacket.TransferData.Data = req.AssetInf.Data;
2800 TransferPacket.TransferData.Status = 1; 2800 TransferPacket.TransferData.Status = 1;
2801 TransferPacket.Header.Zerocoded = true; 2801 TransferPacket.Header.Zerocoded = true;
2802 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); 2802 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2803 } 2803 }
2804 else 2804 else
2805 { 2805 {
@@ -2832,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2832 TransferPacket.TransferData.Status = 1; 2832 TransferPacket.TransferData.Status = 1;
2833 } 2833 }
2834 TransferPacket.Header.Zerocoded = true; 2834 TransferPacket.Header.Zerocoded = true;
2835 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); 2835 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2836 2836
2837 processedLength += chunkSize; 2837 processedLength += chunkSize;
2838 packetNumber++; 2838 packetNumber++;
@@ -3605,7 +3605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3605 } 3605 }
3606 } 3606 }
3607 3607
3608 OutPacket(aw, ThrottleOutPacketType.State); 3608 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3609 } 3609 }
3610 3610
3611 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3611 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3630,7 +3630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3630 avp.Sender.IsTrial = false; 3630 avp.Sender.IsTrial = false;
3631 avp.Sender.ID = agentID; 3631 avp.Sender.ID = agentID;
3632 m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3632 m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3633 OutPacket(avp, ThrottleOutPacketType.State); 3633 OutPacket(avp, ThrottleOutPacketType.Task);
3634 } 3634 }
3635 3635
3636 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3636 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index f675377..e52ac37 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
92 /// <summary>Packets we have sent that need to be ACKed by the client</summary> 92 /// <summary>Packets we have sent that need to be ACKed by the client</summary>
93 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); 93 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
94 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary> 94 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
95 public readonly OpenSim.Framework.LocklessQueue<uint> PendingAcks = new OpenSim.Framework.LocklessQueue<uint>(); 95 public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
96 96
97 /// <summary>Current packet sequence number</summary> 97 /// <summary>Current packet sequence number</summary>
98 public int CurrentSequence; 98 public int CurrentSequence;
@@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
146 /// <summary>Throttle buckets for each packet category</summary> 146 /// <summary>Throttle buckets for each packet category</summary>
147 private readonly TokenBucket[] m_throttleCategories; 147 private readonly TokenBucket[] m_throttleCategories;
148 /// <summary>Outgoing queues for throttled packets</summary> 148 /// <summary>Outgoing queues for throttled packets</summary>
149 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 149 private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
150 /// <summary>A container that can hold one packet for each outbox, used to store 150 /// <summary>A container that can hold one packet for each outbox, used to store
151 /// dequeued packets that are being held for throttling</summary> 151 /// dequeued packets that are being held for throttling</summary>
152 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 152 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
@@ -202,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 ThrottleOutPacketType type = (ThrottleOutPacketType)i; 202 ThrottleOutPacketType type = (ThrottleOutPacketType)i;
203 203
204 // Initialize the packet outboxes, where packets sit while they are waiting for tokens 204 // Initialize the packet outboxes, where packets sit while they are waiting for tokens
205 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 205 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
206 // Initialize the token buckets that control the throttling for each category 206 // Initialize the token buckets that control the throttling for each category
207 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); 207 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
208 } 208 }
@@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
279 public string GetStats() 279 public string GetStats()
280 { 280 {
281 return string.Format( 281 return string.Format(
282 "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}", 282 "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
283 Util.EnvironmentTickCountSubtract(TickLastPacketReceived), 283 Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
284 PacketsReceived, 284 PacketsReceived,
285 PacketsSent, 285 PacketsSent,
@@ -291,8 +291,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
291 m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count, 291 m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count,
292 m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count, 292 m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count,
293 m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count, 293 m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count,
294 m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count, 294 m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count);
295 m_packetOutboxes[(int)ThrottleOutPacketType.State].Count);
296 } 295 }
297 296
298 public void SendPacketStats() 297 public void SendPacketStats()
@@ -338,8 +337,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338 int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 337 int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
339 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 338 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
340 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); 339 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
341 // State is a subcategory of task that we allocate a percentage to
342 int state = 0;
343 340
344 // Make sure none of the throttles are set below our packet MTU, 341 // Make sure none of the throttles are set below our packet MTU,
345 // otherwise a throttle could become permanently clogged 342 // otherwise a throttle could become permanently clogged
@@ -376,9 +373,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
376 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; 373 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
377 bucket.RequestedDripRate = task; 374 bucket.RequestedDripRate = task;
378 375
379 bucket = m_throttleCategories[(int)ThrottleOutPacketType.State];
380 bucket.RequestedDripRate = state;
381
382 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; 376 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
383 bucket.RequestedDripRate = texture; 377 bucket.RequestedDripRate = texture;
384 378
@@ -436,15 +430,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
436 /// </returns> 430 /// </returns>
437 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) 431 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
438 { 432 {
433 return EnqueueOutgoing(packet, forceQueue, false);
434 }
435
436 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority)
437 {
439 int category = (int)packet.Category; 438 int category = (int)packet.Category;
440 439
441 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
442 { 441 {
443 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
444 443
445 if (m_deliverPackets == false) 444 if (m_deliverPackets == false)
446 { 445 {
447 queue.Enqueue(packet); 446 queue.Enqueue(packet, highPriority);
448 return true; 447 return true;
449 } 448 }
450 449
@@ -455,7 +454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
455 // queued packets 454 // queued packets
456 if (queue.Count > 0) 455 if (queue.Count > 0)
457 { 456 {
458 queue.Enqueue(packet); 457 queue.Enqueue(packet, highPriority);
459 return true; 458 return true;
460 } 459 }
461 460
@@ -468,7 +467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 else 467 else
469 { 468 {
470 // Force queue specified or not enough tokens in the bucket, queue this packet 469 // Force queue specified or not enough tokens in the bucket, queue this packet
471 queue.Enqueue(packet); 470 queue.Enqueue(packet, highPriority);
472 return true; 471 return true;
473 } 472 }
474 } 473 }
@@ -500,7 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
500 if (m_deliverPackets == false) return false; 499 if (m_deliverPackets == false) return false;
501 500
502 OutgoingPacket packet = null; 501 OutgoingPacket packet = null;
503 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 DoubleLocklessQueue<OutgoingPacket> queue;
504 TokenBucket bucket; 503 TokenBucket bucket;
505 bool packetSent = false; 504 bool packetSent = false;
506 ThrottleOutPacketTypeFlags emptyCategories = 0; 505 ThrottleOutPacketTypeFlags emptyCategories = 0;
@@ -540,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
540 } 539 }
541 catch 540 catch
542 { 541 {
543 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 542 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
544 } 543 }
545 if (success) 544 if (success)
546 { 545 {
@@ -573,7 +572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
573 } 572 }
574 else 573 else
575 { 574 {
576 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 575 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
577 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
578 } 577 }
579 } 578 }
@@ -709,9 +708,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
709 Texture = 5, 708 Texture = 5,
710 /// <summary>Non-texture assets</summary> 709 /// <summary>Non-texture assets</summary>
711 Asset = 6, 710 Asset = 6,
712 /// <summary>Avatar and primitive data</summary>
713 /// <remarks>This is a sub-category of Task</remarks>
714 State = 7,
715 */ 711 */
716 712
717 switch (category) 713 switch (category)
@@ -728,11 +724,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
728 return ThrottleOutPacketTypeFlags.Texture; 724 return ThrottleOutPacketTypeFlags.Texture;
729 case ThrottleOutPacketType.Asset: 725 case ThrottleOutPacketType.Asset:
730 return ThrottleOutPacketTypeFlags.Asset; 726 return ThrottleOutPacketTypeFlags.Asset;
731 case ThrottleOutPacketType.State:
732 return ThrottleOutPacketTypeFlags.State;
733 default: 727 default:
734 return 0; 728 return 0;
735 } 729 }
736 } 730 }
737 } 731 }
732
733 public class DoubleLocklessQueue<T> : OpenSim.Framework.LocklessQueue<T>
734 {
735 OpenSim.Framework.LocklessQueue<T> highQueue = new OpenSim.Framework.LocklessQueue<T>();
736
737 public override int Count
738 {
739 get
740 {
741 return base.Count + highQueue.Count;
742 }
743 }
744
745 public override bool Dequeue(out T item)
746 {
747 if (highQueue.Dequeue(out item))
748 return true;
749
750 return base.Dequeue(out item);
751 }
752
753 public void Enqueue(T item, bool highPriority)
754 {
755 if (highPriority)
756 highQueue.Enqueue(item);
757 else
758 Enqueue(item);
759 }
760 }
738} 761}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 9a4abd4..6c72edc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -803,6 +803,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
803 803
804 #region Queue or Send 804 #region Queue or Send
805 805
806 bool highPriority = false;
807
808 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
809 {
810 category = (ThrottleOutPacketType)((int)category & 127);
811 highPriority = true;
812 }
813
806 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 814 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
807 // If we were not provided a method for handling unacked, use the UDPServer default method 815 // If we were not provided a method for handling unacked, use the UDPServer default method
808 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 816 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -811,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
811 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 819 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
812 // packet so that it isn't sent before a queued update packet. 820 // packet so that it isn't sent before a queued update packet.
813 bool requestQueue = type == PacketType.KillObject; 821 bool requestQueue = type == PacketType.KillObject;
814 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 822 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
815 SendPacketFinal(outgoingPacket); 823 SendPacketFinal(outgoingPacket);
816 824
817 #endregion Queue or Send 825 #endregion Queue or Send
diff --git a/OpenSim/Region/Framework/Interfaces/ISearchModule.cs b/OpenSim/Region/Framework/Interfaces/ISearchModule.cs
index 64bf72c..d56d188 100644
--- a/OpenSim/Region/Framework/Interfaces/ISearchModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISearchModule.cs
@@ -31,6 +31,6 @@ namespace OpenSim.Framework
31{ 31{
32 public interface ISearchModule 32 public interface ISearchModule
33 { 33 {
34 34 void Refresh();
35 } 35 }
36} 36}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 7fe3109..4f598ea 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.Physics.OdePlugin
68 /// ODE near callback delegate 68 /// ODE near callback delegate
69 /// </summary> 69 /// </summary>
70 private d.NearCallback nearCallback; 70 private d.NearCallback nearCallback;
71 private d.NearCallback nearProbeCallback;
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
73 private List<ContactResult> m_contactResults = new List<ContactResult>(); 72 private List<ContactResult> m_contactResults = new List<ContactResult>();
74 private RayFilterFlags CurrentRayFilter; 73 private RayFilterFlags CurrentRayFilter;
@@ -78,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
78 { 77 {
79 m_scene = pScene; 78 m_scene = pScene;
80 nearCallback = near; 79 nearCallback = near;
81 nearProbeCallback = nearProbe;
82 ray = d.CreateRay(IntPtr.Zero, 1.0f); 80 ray = d.CreateRay(IntPtr.Zero, 1.0f);
83 d.GeomSetCategoryBits(ray, 0); 81 d.GeomSetCategoryBits(ray, 0);
84 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); 82 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
@@ -125,6 +123,24 @@ namespace OpenSim.Region.Physics.OdePlugin
125 { 123 {
126 if (req.callbackMethod != null) 124 if (req.callbackMethod != null)
127 { 125 {
126 IntPtr geom = IntPtr.Zero;
127 if (req.actor != null)
128 {
129 if (m_scene.haveActor(req.actor))
130 {
131 if (req.actor is OdePrim)
132 geom = ((OdePrim)req.actor).prim_geom;
133 else if (req.actor is OdeCharacter)
134 geom = ((OdePrim)req.actor).prim_geom;
135 }
136 if (geom == IntPtr.Zero)
137 {
138 NoContacts(req);
139 continue;
140 }
141 }
142
143
128 CurrentRayFilter = req.filter; 144 CurrentRayFilter = req.filter;
129 CurrentMaxCount = req.Count; 145 CurrentMaxCount = req.Count;
130 146
@@ -188,7 +204,7 @@ namespace OpenSim.Region.Physics.OdePlugin
188 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; 204 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
189 } 205 }
190 206
191 if (req.geom == IntPtr.Zero) 207 if (geom == IntPtr.Zero)
192 { 208 {
193 // translate ray filter to Collision flags 209 // translate ray filter to Collision flags
194 catflags = 0; 210 catflags = 0;
@@ -226,7 +242,7 @@ namespace OpenSim.Region.Physics.OdePlugin
226 catflags |= CollisionCategories.Space; 242 catflags |= CollisionCategories.Space;
227 d.GeomSetCollideBits(Plane, (uint)catflags); 243 d.GeomSetCollideBits(Plane, (uint)catflags);
228 d.GeomSetCategoryBits(Plane, (uint)catflags); 244 d.GeomSetCategoryBits(Plane, (uint)catflags);
229 doPlane(req); 245 doPlane(req,IntPtr.Zero);
230 } 246 }
231 else 247 else
232 { 248 {
@@ -242,12 +258,12 @@ namespace OpenSim.Region.Physics.OdePlugin
242 if (req.callbackMethod is ProbePlaneCallback) 258 if (req.callbackMethod is ProbePlaneCallback)
243 { 259 {
244 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); 260 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
245 doPlane(req); 261 doPlane(req,geom);
246 } 262 }
247 else 263 else
248 { 264 {
249 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); 265 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
250 doGeomRay(req); 266 doGeomRay(req,geom);
251 } 267 }
252 } 268 }
253 } 269 }
@@ -267,6 +283,23 @@ namespace OpenSim.Region.Physics.OdePlugin
267 /// <param name="req"></param> 283 /// <param name="req"></param>
268 /// 284 ///
269 285
286 private void NoContacts(ODERayRequest req)
287 {
288 if (req.callbackMethod is RaycastCallback)
289 {
290 ((RaycastCallback)req.callbackMethod)(false, Vector3.Zero, 0, 0, Vector3.Zero);
291 return;
292 }
293 List<ContactResult> cresult = new List<ContactResult>();
294
295 if (req.callbackMethod is RayCallback)
296 ((RayCallback)req.callbackMethod)(cresult);
297 else if (req.callbackMethod is ProbeBoxCallback)
298 ((ProbeBoxCallback)req.callbackMethod)(cresult);
299 else if (req.callbackMethod is ProbeSphereCallback)
300 ((ProbeSphereCallback)req.callbackMethod)(cresult);
301 }
302
270 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton; 303 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
271// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; 304// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
272 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; 305 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
@@ -358,10 +391,10 @@ namespace OpenSim.Region.Physics.OdePlugin
358 ((ProbeSphereCallback)req.callbackMethod)(cresult); 391 ((ProbeSphereCallback)req.callbackMethod)(cresult);
359 } 392 }
360 393
361 private void doPlane(ODERayRequest req) 394 private void doPlane(ODERayRequest req,IntPtr geom)
362 { 395 {
363 // Collide tests 396 // Collide tests
364 if (req.geom == IntPtr.Zero) 397 if (geom == IntPtr.Zero)
365 { 398 {
366 if ((CurrentRayFilter & FilterActiveSpace) != 0) 399 if ((CurrentRayFilter & FilterActiveSpace) != 0)
367 { 400 {
@@ -375,7 +408,7 @@ namespace OpenSim.Region.Physics.OdePlugin
375 } 408 }
376 else 409 else
377 { 410 {
378 d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); 411 d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback);
379 } 412 }
380 413
381 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); 414 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
@@ -392,10 +425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
392 /// Method that actually initiates the raycast with a geom 425 /// Method that actually initiates the raycast with a geom
393 /// </summary> 426 /// </summary>
394 /// <param name="req"></param> 427 /// <param name="req"></param>
395 private void doGeomRay(ODERayRequest req) 428 private void doGeomRay(ODERayRequest req, IntPtr geom)
396 { 429 {
397 // Collide test 430 // Collide test
398 d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test 431 d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
399 432
400 if (req.callbackMethod is RaycastCallback) 433 if (req.callbackMethod is RaycastCallback)
401 { 434 {
@@ -607,156 +640,6 @@ namespace OpenSim.Region.Physics.OdePlugin
607 } 640 }
608 } 641 }
609 642
610 private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
611 {
612 if (g1 == IntPtr.Zero || g1 == g2)
613 return;
614
615 if (m_contactResults.Count >= CurrentMaxCount)
616 return;
617
618 if (d.GeomIsSpace(g1))
619 {
620 try
621 {
622 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
623 }
624 catch (Exception e)
625 {
626 m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
627 }
628 return;
629 }
630
631 int count = 0;
632 try
633 {
634 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
635 }
636 catch (Exception e)
637 {
638 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
639 return;
640 }
641
642 if (count == 0)
643 return;
644
645 uint ID = 0;
646 PhysicsActor p1 = null;
647
648 m_scene.actor_name_map.TryGetValue(g1, out p1);
649
650 if (p1 == null)
651 return;
652
653 switch (p1.PhysicsActorType)
654 {
655 case (int)ActorTypes.Prim:
656
657 RayFilterFlags thisFlags;
658
659 if (p1.IsPhysical)
660 thisFlags = RayFilterFlags.physical;
661 else
662 thisFlags = RayFilterFlags.nonphysical;
663
664 if (p1.Phantom)
665 thisFlags |= RayFilterFlags.phantom;
666
667 if (p1.IsVolumeDtc)
668 thisFlags |= RayFilterFlags.volumedtc;
669
670 if ((thisFlags & CurrentRayFilter) == 0)
671 return;
672
673 ID = ((OdePrim)p1).LocalID;
674 break;
675
676 case (int)ActorTypes.Agent:
677
678 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
679 return;
680 else
681 ID = ((OdeCharacter)p1).LocalID;
682 break;
683
684 case (int)ActorTypes.Ground:
685
686 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
687 return;
688 break;
689
690 case (int)ActorTypes.Water:
691
692 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
693 return;
694 break;
695
696 default:
697 break;
698 }
699
700 d.ContactGeom curcontact = new d.ContactGeom();
701
702 // closestHit for now only works for meshs, so must do it for others
703 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
704 {
705 // Loop all contacts, build results.
706 for (int i = 0; i < count; i++)
707 {
708 if (!GetCurContactGeom(i, ref curcontact))
709 break;
710
711 ContactResult collisionresult = new ContactResult();
712 collisionresult.ConsumerID = ID;
713 collisionresult.Pos.X = curcontact.pos.X;
714 collisionresult.Pos.Y = curcontact.pos.Y;
715 collisionresult.Pos.Z = curcontact.pos.Z;
716 collisionresult.Depth = curcontact.depth;
717 collisionresult.Normal.X = curcontact.normal.X;
718 collisionresult.Normal.Y = curcontact.normal.Y;
719 collisionresult.Normal.Z = curcontact.normal.Z;
720 lock (m_contactResults)
721 {
722 m_contactResults.Add(collisionresult);
723 if (m_contactResults.Count >= CurrentMaxCount)
724 return;
725 }
726 }
727 }
728 else
729 {
730 // keep only closest contact
731 ContactResult collisionresult = new ContactResult();
732 collisionresult.ConsumerID = ID;
733 collisionresult.Depth = float.MaxValue;
734
735 for (int i = 0; i < count; i++)
736 {
737 if (!GetCurContactGeom(i, ref curcontact))
738 break;
739
740 if (curcontact.depth < collisionresult.Depth)
741 {
742 collisionresult.Pos.X = curcontact.pos.X;
743 collisionresult.Pos.Y = curcontact.pos.Y;
744 collisionresult.Pos.Z = curcontact.pos.Z;
745 collisionresult.Depth = curcontact.depth;
746 collisionresult.Normal.X = curcontact.normal.X;
747 collisionresult.Normal.Y = curcontact.normal.Y;
748 collisionresult.Normal.Z = curcontact.normal.Z;
749 }
750 }
751
752 if (collisionresult.Depth != float.MaxValue)
753 {
754 lock (m_contactResults)
755 m_contactResults.Add(collisionresult);
756 }
757 }
758 }
759
760 /// <summary> 643 /// <summary>
761 /// Dereference the creator scene so that it can be garbage collected if needed. 644 /// Dereference the creator scene so that it can be garbage collected if needed.
762 /// </summary> 645 /// </summary>
@@ -788,7 +671,7 @@ namespace OpenSim.Region.Physics.OdePlugin
788 671
789 public struct ODERayRequest 672 public struct ODERayRequest
790 { 673 {
791 public IntPtr geom; 674 public PhysicsActor actor;
792 public Vector3 Origin; 675 public Vector3 Origin;
793 public Vector3 Normal; 676 public Vector3 Normal;
794 public int Count; 677 public int Count;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 0d18adb..5113210 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -2580,7 +2580,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2580 if (retMethod != null) 2580 if (retMethod != null)
2581 { 2581 {
2582 ODERayRequest req = new ODERayRequest(); 2582 ODERayRequest req = new ODERayRequest();
2583 req.geom = IntPtr.Zero; 2583 req.actor = null;
2584 req.callbackMethod = retMethod; 2584 req.callbackMethod = retMethod;
2585 req.length = length; 2585 req.length = length;
2586 req.Normal = direction; 2586 req.Normal = direction;
@@ -2597,7 +2597,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2597 if (retMethod != null) 2597 if (retMethod != null)
2598 { 2598 {
2599 ODERayRequest req = new ODERayRequest(); 2599 ODERayRequest req = new ODERayRequest();
2600 req.geom = IntPtr.Zero; 2600 req.actor = null;
2601 req.callbackMethod = retMethod; 2601 req.callbackMethod = retMethod;
2602 req.length = length; 2602 req.length = length;
2603 req.Normal = direction; 2603 req.Normal = direction;
@@ -2625,7 +2625,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2625 }; 2625 };
2626 2626
2627 ODERayRequest req = new ODERayRequest(); 2627 ODERayRequest req = new ODERayRequest();
2628 req.geom = IntPtr.Zero; 2628 req.actor = null;
2629 req.callbackMethod = retMethod; 2629 req.callbackMethod = retMethod;
2630 req.length = length; 2630 req.length = length;
2631 req.Normal = direction; 2631 req.Normal = direction;
@@ -2663,7 +2663,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2663 }; 2663 };
2664 2664
2665 ODERayRequest req = new ODERayRequest(); 2665 ODERayRequest req = new ODERayRequest();
2666 req.geom = IntPtr.Zero; 2666 req.actor = null;
2667 req.callbackMethod = retMethod; 2667 req.callbackMethod = retMethod;
2668 req.length = length; 2668 req.length = length;
2669 req.Normal = direction; 2669 req.Normal = direction;
@@ -2710,7 +2710,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2710 }; 2710 };
2711 2711
2712 ODERayRequest req = new ODERayRequest(); 2712 ODERayRequest req = new ODERayRequest();
2713 req.geom = geom; 2713 req.actor = actor;
2714 req.callbackMethod = retMethod; 2714 req.callbackMethod = retMethod;
2715 req.length = length; 2715 req.length = length;
2716 req.Normal = direction; 2716 req.Normal = direction;
@@ -2745,7 +2745,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2745 }; 2745 };
2746 2746
2747 ODERayRequest req = new ODERayRequest(); 2747 ODERayRequest req = new ODERayRequest();
2748 req.geom = IntPtr.Zero; 2748 req.actor = null;
2749 req.callbackMethod = retMethod; 2749 req.callbackMethod = retMethod;
2750 req.Normal = size; 2750 req.Normal = size;
2751 req.Origin = position; 2751 req.Origin = position;
@@ -2777,7 +2777,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2777 }; 2777 };
2778 2778
2779 ODERayRequest req = new ODERayRequest(); 2779 ODERayRequest req = new ODERayRequest();
2780 req.geom = IntPtr.Zero; 2780 req.actor = null;
2781 req.callbackMethod = retMethod; 2781 req.callbackMethod = retMethod;
2782 req.length = radius; 2782 req.length = radius;
2783 req.Origin = position; 2783 req.Origin = position;
@@ -2819,7 +2819,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2819 }; 2819 };
2820 2820
2821 ODERayRequest req = new ODERayRequest(); 2821 ODERayRequest req = new ODERayRequest();
2822 req.geom = geom; 2822 req.actor = null;
2823 req.callbackMethod = retMethod; 2823 req.callbackMethod = retMethod;
2824 req.length = plane.W; 2824 req.length = plane.W;
2825 req.Normal.X = plane.X; 2825 req.Normal.X = plane.X;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 1e1e574..525e575 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2260,7 +2260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2260 return end; 2260 return end;
2261 } 2261 }
2262 2262
2263 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2263 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2264 { 2264 {
2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2266 return fromPos; 2266 return fromPos;
@@ -2276,9 +2276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2276 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2276 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2277 targetPos.z = ground; 2277 targetPos.z = ground;
2278 } 2278 }
2279 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2279 if (adjust)
2280 return SetPosAdjust(fromPos, targetPos);
2280 2281
2281 return real_vec; 2282 return targetPos;
2282 } 2283 }
2283 2284
2284 /// <summary> 2285 /// <summary>
@@ -2293,7 +2294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2293 return; 2294 return;
2294 2295
2295 LSL_Vector currentPos = GetPartLocalPos(part); 2296 LSL_Vector currentPos = GetPartLocalPos(part);
2296 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos); 2297 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2297 2298
2298 2299
2299 if (part.ParentGroup.RootPart == part) 2300 if (part.ParentGroup.RootPart == part)
@@ -7925,7 +7926,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7925 return null; 7926 return null;
7926 7927
7927 v=rules.GetVector3Item(idx++); 7928 v=rules.GetVector3Item(idx++);
7928 currentPosition = GetSetPosTarget(part, v, currentPosition); 7929 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7930 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7931 else
7932 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7929 positionChanged = true; 7933 positionChanged = true;
7930 7934
7931 break; 7935 break;