Merge remote-tracking branch 'remotes/origin/avination' into teravuswork

avinationmerge
teravus 2013-01-16 17:52:02 -05:00
commit 670bb9cb8b
11 changed files with 167 additions and 216 deletions

View File

@ -157,6 +157,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove); availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove);
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
// Misc
availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
// Either enable full remote functionality or just selected features // Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all"); string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -1948,6 +1951,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
responseData["success"] = true; responseData["success"] = true;
} }
private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Refresh Search Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
CheckRegionParams(requestData, responseData);
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
if (searchModule != null)
{
searchModule.Refresh();
responseData["success"] = true;
}
else
{
responseData["success"] = false;
}
m_log.Info("[RADMIN]: Refresh Search Request complete");
}
/// <summary> /// <summary>
/// Parse a float with the given parameter name from a request data hash table. /// Parse a float with the given parameter name from a request data hash table.
/// </summary> /// </summary>

View File

@ -29,7 +29,7 @@ using System.Threading;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public sealed class LocklessQueue<T> public class LocklessQueue<T>
{ {
private sealed class SingleLinkNode private sealed class SingleLinkNode
{ {
@ -41,7 +41,7 @@ namespace OpenSim.Framework
SingleLinkNode tail; SingleLinkNode tail;
int count; int count;
public int Count { get { return count; } } public virtual int Count { get { return count; } }
public LocklessQueue() public LocklessQueue()
{ {
@ -76,7 +76,7 @@ namespace OpenSim.Framework
Interlocked.Increment(ref count); Interlocked.Increment(ref count);
} }
public bool Dequeue(out T item) public virtual bool Dequeue(out T item)
{ {
item = default(T); item = default(T);
SingleLinkNode oldHead = null; SingleLinkNode oldHead = null;

View File

@ -47,9 +47,8 @@ namespace OpenSim.Framework
Texture = 5, Texture = 5,
/// <summary>Non-texture assets</summary> /// <summary>Non-texture assets</summary>
Asset = 6, Asset = 6,
/// <summary>Avatar and primitive data</summary>
/// <remarks>This is a sub-category of Task</remarks> HighPriority = 128,
State = 7,
} }
[Flags] [Flags]
@ -61,6 +60,5 @@ namespace OpenSim.Framework
Task = 1 << 3, Task = 1 << 3,
Texture = 1 << 4, Texture = 1 << 4,
Asset = 1 << 5, Asset = 1 << 5,
State = 1 << 6,
} }
} }

View File

@ -501,7 +501,8 @@ namespace OpenSim.Region.ClientStack.Linden
ScenePresence p; ScenePresence p;
if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore. if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore.
{ {
AlterThrottle(UserSetThrottle, p); // AlterThrottle(UserSetThrottle, p);
UpdateThrottle(UserSetThrottle, p);
} }
} }
} }
@ -546,7 +547,12 @@ namespace OpenSim.Region.ClientStack.Linden
// Client set throttle ! // Client set throttle !
UserSetThrottle = pimagethrottle; UserSetThrottle = pimagethrottle;
CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon); CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon)); // UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
float udp = 1.0f - CapThrottleDistributon;
if(udp < 0.5f)
udp = 0.5f;
UDPSetThrottle = (int) ((float)pimagethrottle * udp);
if (CapSetThrottle < 4068) if (CapSetThrottle < 4068)
CapSetThrottle = 4068; // at least two discovery mesh CapSetThrottle = 4068; // at least two discovery mesh
p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle); p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);

View File

@ -1607,7 +1607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
{ {
OutPacket(kill, ThrottleOutPacketType.State); OutPacket(kill, ThrottleOutPacketType.Task);
} }
else else
{ {
@ -2788,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Transfer.TransferInfo.Size = req.AssetInf.Data.Length; Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
Transfer.TransferInfo.TransferID = req.TransferRequestID; Transfer.TransferInfo.TransferID = req.TransferRequestID;
Transfer.Header.Zerocoded = true; Transfer.Header.Zerocoded = true;
OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
if (req.NumPackets == 1) if (req.NumPackets == 1)
{ {
@ -2799,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TransferPacket.TransferData.Data = req.AssetInf.Data; TransferPacket.TransferData.Data = req.AssetInf.Data;
TransferPacket.TransferData.Status = 1; TransferPacket.TransferData.Status = 1;
TransferPacket.Header.Zerocoded = true; TransferPacket.Header.Zerocoded = true;
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
} }
else else
{ {
@ -2832,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TransferPacket.TransferData.Status = 1; TransferPacket.TransferData.Status = 1;
} }
TransferPacket.Header.Zerocoded = true; TransferPacket.Header.Zerocoded = true;
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
processedLength += chunkSize; processedLength += chunkSize;
packetNumber++; packetNumber++;
@ -3605,7 +3605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
OutPacket(aw, ThrottleOutPacketType.State); OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
} }
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@ -3630,7 +3630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
avp.Sender.IsTrial = false; avp.Sender.IsTrial = false;
avp.Sender.ID = agentID; avp.Sender.ID = agentID;
m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
OutPacket(avp, ThrottleOutPacketType.State); OutPacket(avp, ThrottleOutPacketType.Task);
} }
public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)

View File

@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Packets we have sent that need to be ACKed by the client</summary> /// <summary>Packets we have sent that need to be ACKed by the client</summary>
public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
/// <summary>ACKs that are queued up, waiting to be sent to the client</summary> /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
public readonly OpenSim.Framework.LocklessQueue<uint> PendingAcks = new OpenSim.Framework.LocklessQueue<uint>(); public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
/// <summary>Current packet sequence number</summary> /// <summary>Current packet sequence number</summary>
public int CurrentSequence; public int CurrentSequence;
@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Throttle buckets for each packet category</summary> /// <summary>Throttle buckets for each packet category</summary>
private readonly TokenBucket[] m_throttleCategories; private readonly TokenBucket[] m_throttleCategories;
/// <summary>Outgoing queues for throttled packets</summary> /// <summary>Outgoing queues for throttled packets</summary>
private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
/// <summary>A container that can hold one packet for each outbox, used to store /// <summary>A container that can hold one packet for each outbox, used to store
/// dequeued packets that are being held for throttling</summary> /// dequeued packets that are being held for throttling</summary>
private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
@ -202,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ThrottleOutPacketType type = (ThrottleOutPacketType)i; ThrottleOutPacketType type = (ThrottleOutPacketType)i;
// Initialize the packet outboxes, where packets sit while they are waiting for tokens // Initialize the packet outboxes, where packets sit while they are waiting for tokens
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
// Initialize the token buckets that control the throttling for each category // Initialize the token buckets that control the throttling for each category
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
} }
@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats() public string GetStats()
{ {
return string.Format( return string.Format(
"{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}", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
Util.EnvironmentTickCountSubtract(TickLastPacketReceived), Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
PacketsReceived, PacketsReceived,
PacketsSent, PacketsSent,
@ -291,8 +291,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count);
m_packetOutboxes[(int)ThrottleOutPacketType.State].Count);
} }
public void SendPacketStats() public void SendPacketStats()
@ -338,8 +337,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// State is a subcategory of task that we allocate a percentage to
int state = 0;
// Make sure none of the throttles are set below our packet MTU, // Make sure none of the throttles are set below our packet MTU,
// otherwise a throttle could become permanently clogged // otherwise a throttle could become permanently clogged
@ -376,9 +373,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
bucket.RequestedDripRate = task; bucket.RequestedDripRate = task;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.State];
bucket.RequestedDripRate = state;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
bucket.RequestedDripRate = texture; bucket.RequestedDripRate = texture;
@ -435,16 +429,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// false if the packet has not been queued and should be sent immediately. /// false if the packet has not been queued and should be sent immediately.
/// </returns> /// </returns>
public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
{
return EnqueueOutgoing(packet, forceQueue, false);
}
public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority)
{ {
int category = (int)packet.Category; int category = (int)packet.Category;
if (category >= 0 && category < m_packetOutboxes.Length) if (category >= 0 && category < m_packetOutboxes.Length)
{ {
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
if (m_deliverPackets == false) if (m_deliverPackets == false)
{ {
queue.Enqueue(packet); queue.Enqueue(packet, highPriority);
return true; return true;
} }
@ -455,7 +454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// queued packets // queued packets
if (queue.Count > 0) if (queue.Count > 0)
{ {
queue.Enqueue(packet); queue.Enqueue(packet, highPriority);
return true; return true;
} }
@ -468,7 +467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else else
{ {
// Force queue specified or not enough tokens in the bucket, queue this packet // Force queue specified or not enough tokens in the bucket, queue this packet
queue.Enqueue(packet); queue.Enqueue(packet, highPriority);
return true; return true;
} }
} }
@ -500,7 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_deliverPackets == false) return false; if (m_deliverPackets == false) return false;
OutgoingPacket packet = null; OutgoingPacket packet = null;
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; DoubleLocklessQueue<OutgoingPacket> queue;
TokenBucket bucket; TokenBucket bucket;
bool packetSent = false; bool packetSent = false;
ThrottleOutPacketTypeFlags emptyCategories = 0; ThrottleOutPacketTypeFlags emptyCategories = 0;
@ -540,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
catch catch
{ {
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
} }
if (success) if (success)
{ {
@ -573,7 +572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
emptyCategories |= CategoryToFlag(i); emptyCategories |= CategoryToFlag(i);
} }
} }
@ -709,9 +708,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Texture = 5, Texture = 5,
/// <summary>Non-texture assets</summary> /// <summary>Non-texture assets</summary>
Asset = 6, Asset = 6,
/// <summary>Avatar and primitive data</summary>
/// <remarks>This is a sub-category of Task</remarks>
State = 7,
*/ */
switch (category) switch (category)
@ -728,11 +724,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return ThrottleOutPacketTypeFlags.Texture; return ThrottleOutPacketTypeFlags.Texture;
case ThrottleOutPacketType.Asset: case ThrottleOutPacketType.Asset:
return ThrottleOutPacketTypeFlags.Asset; return ThrottleOutPacketTypeFlags.Asset;
case ThrottleOutPacketType.State:
return ThrottleOutPacketTypeFlags.State;
default: default:
return 0; return 0;
} }
} }
} }
public class DoubleLocklessQueue<T> : OpenSim.Framework.LocklessQueue<T>
{
OpenSim.Framework.LocklessQueue<T> highQueue = new OpenSim.Framework.LocklessQueue<T>();
public override int Count
{
get
{
return base.Count + highQueue.Count;
}
}
public override bool Dequeue(out T item)
{
if (highQueue.Dequeue(out item))
return true;
return base.Dequeue(out item);
}
public void Enqueue(T item, bool highPriority)
{
if (highPriority)
highQueue.Enqueue(item);
else
Enqueue(item);
}
}
} }

View File

@ -803,6 +803,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Queue or Send #region Queue or Send
bool highPriority = false;
if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
{
category = (ThrottleOutPacketType)((int)category & 127);
highPriority = true;
}
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
// If we were not provided a method for handling unacked, use the UDPServer default method // If we were not provided a method for handling unacked, use the UDPServer default method
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@ -811,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
// packet so that it isn't sent before a queued update packet. // packet so that it isn't sent before a queued update packet.
bool requestQueue = type == PacketType.KillObject; bool requestQueue = type == PacketType.KillObject;
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
SendPacketFinal(outgoingPacket); SendPacketFinal(outgoingPacket);
#endregion Queue or Send #endregion Queue or Send

View File

@ -31,6 +31,6 @@ namespace OpenSim.Framework
{ {
public interface ISearchModule public interface ISearchModule
{ {
void Refresh();
} }
} }

View File

@ -68,7 +68,6 @@ namespace OpenSim.Region.Physics.OdePlugin
/// ODE near callback delegate /// ODE near callback delegate
/// </summary> /// </summary>
private d.NearCallback nearCallback; private d.NearCallback nearCallback;
private d.NearCallback nearProbeCallback;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<ContactResult> m_contactResults = new List<ContactResult>(); private List<ContactResult> m_contactResults = new List<ContactResult>();
private RayFilterFlags CurrentRayFilter; private RayFilterFlags CurrentRayFilter;
@ -78,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_scene = pScene; m_scene = pScene;
nearCallback = near; nearCallback = near;
nearProbeCallback = nearProbe;
ray = d.CreateRay(IntPtr.Zero, 1.0f); ray = d.CreateRay(IntPtr.Zero, 1.0f);
d.GeomSetCategoryBits(ray, 0); d.GeomSetCategoryBits(ray, 0);
Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
@ -125,6 +123,24 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (req.callbackMethod != null) if (req.callbackMethod != null)
{ {
IntPtr geom = IntPtr.Zero;
if (req.actor != null)
{
if (m_scene.haveActor(req.actor))
{
if (req.actor is OdePrim)
geom = ((OdePrim)req.actor).prim_geom;
else if (req.actor is OdeCharacter)
geom = ((OdePrim)req.actor).prim_geom;
}
if (geom == IntPtr.Zero)
{
NoContacts(req);
continue;
}
}
CurrentRayFilter = req.filter; CurrentRayFilter = req.filter;
CurrentMaxCount = req.Count; CurrentMaxCount = req.Count;
@ -188,7 +204,7 @@ namespace OpenSim.Region.Physics.OdePlugin
CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
} }
if (req.geom == IntPtr.Zero) if (geom == IntPtr.Zero)
{ {
// translate ray filter to Collision flags // translate ray filter to Collision flags
catflags = 0; catflags = 0;
@ -226,7 +242,7 @@ namespace OpenSim.Region.Physics.OdePlugin
catflags |= CollisionCategories.Space; catflags |= CollisionCategories.Space;
d.GeomSetCollideBits(Plane, (uint)catflags); d.GeomSetCollideBits(Plane, (uint)catflags);
d.GeomSetCategoryBits(Plane, (uint)catflags); d.GeomSetCategoryBits(Plane, (uint)catflags);
doPlane(req); doPlane(req,IntPtr.Zero);
} }
else else
{ {
@ -242,12 +258,12 @@ namespace OpenSim.Region.Physics.OdePlugin
if (req.callbackMethod is ProbePlaneCallback) if (req.callbackMethod is ProbePlaneCallback)
{ {
d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
doPlane(req); doPlane(req,geom);
} }
else else
{ {
d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
doGeomRay(req); doGeomRay(req,geom);
} }
} }
} }
@ -267,6 +283,23 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="req"></param> /// <param name="req"></param>
/// ///
private void NoContacts(ODERayRequest req)
{
if (req.callbackMethod is RaycastCallback)
{
((RaycastCallback)req.callbackMethod)(false, Vector3.Zero, 0, 0, Vector3.Zero);
return;
}
List<ContactResult> cresult = new List<ContactResult>();
if (req.callbackMethod is RayCallback)
((RayCallback)req.callbackMethod)(cresult);
else if (req.callbackMethod is ProbeBoxCallback)
((ProbeBoxCallback)req.callbackMethod)(cresult);
else if (req.callbackMethod is ProbeSphereCallback)
((ProbeSphereCallback)req.callbackMethod)(cresult);
}
private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton; private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; // private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
@ -358,10 +391,10 @@ namespace OpenSim.Region.Physics.OdePlugin
((ProbeSphereCallback)req.callbackMethod)(cresult); ((ProbeSphereCallback)req.callbackMethod)(cresult);
} }
private void doPlane(ODERayRequest req) private void doPlane(ODERayRequest req,IntPtr geom)
{ {
// Collide tests // Collide tests
if (req.geom == IntPtr.Zero) if (geom == IntPtr.Zero)
{ {
if ((CurrentRayFilter & FilterActiveSpace) != 0) if ((CurrentRayFilter & FilterActiveSpace) != 0)
{ {
@ -375,7 +408,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
else else
{ {
d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback);
} }
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
@ -392,10 +425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
/// Method that actually initiates the raycast with a geom /// Method that actually initiates the raycast with a geom
/// </summary> /// </summary>
/// <param name="req"></param> /// <param name="req"></param>
private void doGeomRay(ODERayRequest req) private void doGeomRay(ODERayRequest req, IntPtr geom)
{ {
// Collide test // Collide test
d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
if (req.callbackMethod is RaycastCallback) if (req.callbackMethod is RaycastCallback)
{ {
@ -607,156 +640,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
{
if (g1 == IntPtr.Zero || g1 == g2)
return;
if (m_contactResults.Count >= CurrentMaxCount)
return;
if (d.GeomIsSpace(g1))
{
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
}
return;
}
int count = 0;
try
{
count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
return;
}
if (count == 0)
return;
uint ID = 0;
PhysicsActor p1 = null;
m_scene.actor_name_map.TryGetValue(g1, out p1);
if (p1 == null)
return;
switch (p1.PhysicsActorType)
{
case (int)ActorTypes.Prim:
RayFilterFlags thisFlags;
if (p1.IsPhysical)
thisFlags = RayFilterFlags.physical;
else
thisFlags = RayFilterFlags.nonphysical;
if (p1.Phantom)
thisFlags |= RayFilterFlags.phantom;
if (p1.IsVolumeDtc)
thisFlags |= RayFilterFlags.volumedtc;
if ((thisFlags & CurrentRayFilter) == 0)
return;
ID = ((OdePrim)p1).LocalID;
break;
case (int)ActorTypes.Agent:
if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
return;
else
ID = ((OdeCharacter)p1).LocalID;
break;
case (int)ActorTypes.Ground:
if ((CurrentRayFilter & RayFilterFlags.land) == 0)
return;
break;
case (int)ActorTypes.Water:
if ((CurrentRayFilter & RayFilterFlags.water) == 0)
return;
break;
default:
break;
}
d.ContactGeom curcontact = new d.ContactGeom();
// closestHit for now only works for meshs, so must do it for others
if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
{
// Loop all contacts, build results.
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ID;
collisionresult.Pos.X = curcontact.pos.X;
collisionresult.Pos.Y = curcontact.pos.Y;
collisionresult.Pos.Z = curcontact.pos.Z;
collisionresult.Depth = curcontact.depth;
collisionresult.Normal.X = curcontact.normal.X;
collisionresult.Normal.Y = curcontact.normal.Y;
collisionresult.Normal.Z = curcontact.normal.Z;
lock (m_contactResults)
{
m_contactResults.Add(collisionresult);
if (m_contactResults.Count >= CurrentMaxCount)
return;
}
}
}
else
{
// keep only closest contact
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ID;
collisionresult.Depth = float.MaxValue;
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
if (curcontact.depth < collisionresult.Depth)
{
collisionresult.Pos.X = curcontact.pos.X;
collisionresult.Pos.Y = curcontact.pos.Y;
collisionresult.Pos.Z = curcontact.pos.Z;
collisionresult.Depth = curcontact.depth;
collisionresult.Normal.X = curcontact.normal.X;
collisionresult.Normal.Y = curcontact.normal.Y;
collisionresult.Normal.Z = curcontact.normal.Z;
}
}
if (collisionresult.Depth != float.MaxValue)
{
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
/// <summary> /// <summary>
/// Dereference the creator scene so that it can be garbage collected if needed. /// Dereference the creator scene so that it can be garbage collected if needed.
/// </summary> /// </summary>
@ -788,7 +671,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public struct ODERayRequest public struct ODERayRequest
{ {
public IntPtr geom; public PhysicsActor actor;
public Vector3 Origin; public Vector3 Origin;
public Vector3 Normal; public Vector3 Normal;
public int Count; public int Count;

View File

@ -2580,7 +2580,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (retMethod != null) if (retMethod != null)
{ {
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2597,7 +2597,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (retMethod != null) if (retMethod != null)
{ {
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2625,7 +2625,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2663,7 +2663,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2710,7 +2710,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = geom; req.actor = actor;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2745,7 +2745,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.Normal = size; req.Normal = size;
req.Origin = position; req.Origin = position;
@ -2777,7 +2777,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = radius; req.length = radius;
req.Origin = position; req.Origin = position;
@ -2819,7 +2819,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = geom; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = plane.W; req.length = plane.W;
req.Normal.X = plane.X; req.Normal.X = plane.X;

View File

@ -2260,7 +2260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return end; return end;
} }
protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
{ {
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return fromPos; return fromPos;
@ -2276,9 +2276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
targetPos.z = ground; targetPos.z = ground;
} }
LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); if (adjust)
return SetPosAdjust(fromPos, targetPos);
return real_vec; return targetPos;
} }
/// <summary> /// <summary>
@ -2293,7 +2294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return; return;
LSL_Vector currentPos = GetPartLocalPos(part); LSL_Vector currentPos = GetPartLocalPos(part);
LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos); LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
if (part.ParentGroup.RootPart == part) if (part.ParentGroup.RootPart == part)
@ -7925,7 +7926,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return null; return null;
v=rules.GetVector3Item(idx++); v=rules.GetVector3Item(idx++);
currentPosition = GetSetPosTarget(part, v, currentPosition); if (part.IsRoot && !part.ParentGroup.IsAttachment)
currentPosition = GetSetPosTarget(part, v, currentPosition, true);
else
currentPosition = GetSetPosTarget(part, v, currentPosition, false);
positionChanged = true; positionChanged = true;
break; break;