Let llCastRay use ubitODE raycast if avaiable plus a few changes/fixes that should be checked. PROBLEM: it will not detect nonphysical phantons :(

avinationmerge
UbitUmarov 2012-04-16 16:35:35 +01:00
parent 25a2f97bc2
commit f05a977afa
1 changed files with 86 additions and 22 deletions

View File

@ -11869,38 +11869,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
if (checkTerrain)
{
ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
if (groundContact != null)
results.Add((ContactResult)groundContact);
}
if (checkAgents) if (World.SuportsRayCastFiltered())
{ {
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); if (dist == 0)
foreach (ContactResult r in agentHits) return list;
results.Add(r);
}
if (checkPhysical || checkNonPhysical) 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);
}
// bug: will not detect phantom unless they are physical
// don't use ObjectIntersection because its also bad
}
else
{ {
ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); if (checkTerrain)
foreach (ContactResult r in objectHits) {
results.Add(r); ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
if (groundContact != null)
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 (int)(a.Depth - b.Depth); return a.Depth.CompareTo(b.Depth);
}); });
int values = 0; int values = 0;
SceneObjectGroup thisgrp = m_host.ParentGroup;
foreach (ContactResult result in results) foreach (ContactResult result in results)
{ {
if (result.Depth > dist) if (result.Depth > dist)
continue; continue;
// physics ray can return colisions with host prim
if (m_host.LocalId == result.ConsumerID)
continue;
UUID itemID = UUID.Zero; UUID itemID = UUID.Zero;
int linkNum = 0; int linkNum = 0;
@ -11908,6 +11971,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// It's a prim! // It's a prim!
if (part != null) if (part != null)
{ {
// dont detect members of same object ???
if (part.ParentGroup == thisgrp)
continue;
if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY) if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
itemID = part.ParentGroup.UUID; itemID = part.ParentGroup.UUID;
else else
@ -11918,7 +11985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else else
{ {
ScenePresence sp = World.GetScenePresence(result.ConsumerID); ScenePresence sp = World.GetScenePresence(result.ConsumerID);
/// It it a boy? a girl? /// It it a boy? a girl?
if (sp != null) if (sp != null)
itemID = sp.UUID; itemID = sp.UUID;
} }
@ -11929,14 +11996,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
list.Add(new LSL_Integer(linkNum)); list.Add(new LSL_Integer(linkNum));
if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
values++;
count--;
if (count == 0) values++;
if (values >= count)
break; break;
} }