Add the Avination physics raycast glue so Core Physics can implement raycast
parent
6a2b673fca
commit
c1795ed399
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue