Add the Avination physics raycast glue so Core Physics can implement raycast

user_profiles
Melanie 2013-01-23 21:03:24 +00:00
parent 6a2b673fca
commit c1795ed399
3 changed files with 130 additions and 14 deletions

View File

@ -1983,6 +1983,19 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerPrimsLoaded(this); EventManager.TriggerPrimsLoaded(this);
} }
public bool SupportsRayCastFiltered()
{
if (PhysicsScene == null)
return false;
return PhysicsScene.SupportsRaycastWorldFiltered();
}
public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
{
if (PhysicsScene == null)
return null;
return PhysicsScene.RaycastWorld(position, direction, length, Count,filter);
}
/// <summary> /// <summary>
/// Gets a new rez location based on the raycast and the size of the object that is being rezzed. /// Gets a new rez location based on the raycast and the size of the object that is being rezzed.

View File

@ -43,6 +43,35 @@ namespace OpenSim.Region.Physics.Manager
public delegate void JointDeactivated(PhysicsJoint joint); public delegate void JointDeactivated(PhysicsJoint joint);
public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation"
public enum RayFilterFlags:ushort
{
// the flags
water = 0x01,
land = 0x02,
agent = 0x04,
nonphysical = 0x08,
physical = 0x10,
phantom = 0x20,
volumedtc = 0x40,
// ray cast colision control (may only work for meshs)
ContactsUnImportant = 0x2000,
BackFaceCull = 0x4000,
ClosestHit = 0x8000,
// some combinations
LSLPhanton = phantom | volumedtc,
PrimsNonPhantom = nonphysical | physical,
PrimsNonPhantomAgents = nonphysical | physical | agent,
AllPrims = nonphysical | phantom | volumedtc | physical,
AllButLand = agent | nonphysical | physical | phantom | volumedtc,
ClosestAndBackCull = ClosestHit | BackFaceCull,
All = 0x3f
}
public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback); public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback);
public delegate void AssetReceivedDelegate(AssetBase asset); public delegate void AssetReceivedDelegate(AssetBase asset);
@ -286,5 +315,15 @@ namespace OpenSim.Region.Physics.Manager
{ {
return new List<ContactResult>(); return new List<ContactResult>();
} }
public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
{
return null;
}
public virtual bool SupportsRaycastWorldFiltered()
{
return false;
}
} }
} }

View File

@ -11340,6 +11340,84 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
if (World.SupportsRayCastFiltered())
{
if (dist == 0)
return list;
RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
if (checkTerrain)
rayfilter |= RayFilterFlags.land;
// if (checkAgents)
// rayfilter |= RayFilterFlags.agent;
if (checkPhysical)
rayfilter |= RayFilterFlags.physical;
if (checkNonPhysical)
rayfilter |= RayFilterFlags.nonphysical;
if (detectPhantom)
rayfilter |= RayFilterFlags.LSLPhanton;
Vector3 direction = dir * ( 1/dist);
if(rayfilter == 0)
{
list.Add(new LSL_Integer(0));
return list;
}
// get some more contacts to sort ???
int physcount = 4 * count;
if (physcount > 20)
physcount = 20;
object physresults;
physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
if (physresults == null)
{
list.Add(new LSL_Integer(-3)); // timeout error
return list;
}
results = (List<ContactResult>)physresults;
// for now physics doesn't detect sitted avatars so do it outside physics
if (checkAgents)
{
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
foreach (ContactResult r in agentHits)
results.Add(r);
}
// TODO: Replace this with a better solution. ObjectIntersection can only
// detect nonphysical phantoms. They are detected by virtue of being
// nonphysical (e.g. no PhysActor) so will not conflict with detecting
// physicsl phantoms as done by the physics scene
// We don't want anything else but phantoms here.
if (detectPhantom)
{
ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
foreach (ContactResult r in objectHits)
results.Add(r);
}
}
else
{
if (checkAgents)
{
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
foreach (ContactResult r in agentHits)
results.Add(r);
}
if (checkPhysical || checkNonPhysical || detectPhantom)
{
ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
foreach (ContactResult r in objectHits)
results.Add(r);
}
}
if (checkTerrain) if (checkTerrain)
{ {
ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
@ -11347,20 +11425,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
results.Add((ContactResult)groundContact); results.Add((ContactResult)groundContact);
} }
if (checkAgents)
{
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
foreach (ContactResult r in agentHits)
results.Add(r);
}
if (checkPhysical || checkNonPhysical || detectPhantom)
{
ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
foreach (ContactResult r in objectHits)
results.Add(r);
}
results.Sort(delegate(ContactResult a, ContactResult b) results.Sort(delegate(ContactResult a, ContactResult b)
{ {
return a.Depth.CompareTo(b.Depth); return a.Depth.CompareTo(b.Depth);