restrict ubOde castray with terrain range only on horizontal plane, let it find physical avatars.

melanie
UbitUmarov 2016-11-06 03:53:12 +00:00
parent d07f48605f
commit 014cd1ab42
2 changed files with 23 additions and 10 deletions

View File

@ -317,8 +317,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// current ode land to ray collisions is very bad // current ode land to ray collisions is very bad
// so for now limit its range badly // so for now limit its range badly
if (req.length > 60.0f) if (req.length > 60.0f)
d.GeomRaySetLength(ray, 60.0f); {
Vector3 t = req.Normal * req.length;
float tmp = t.X * t.X + t.Y * t.Y;
if(tmp > 2500)
{
float tmp2 = req.length * req.length - tmp + 2500;
tmp2 = (float)Math.Sqrt(tmp2);
d.GeomRaySetLength(ray, tmp2);
}
}
d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback); d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
} }

View File

@ -14216,18 +14216,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return false; return false;
} }
private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd, bool skipPhys)
{ {
List<ContactResult> contacts = new List<ContactResult>(); List<ContactResult> contacts = new List<ContactResult>();
Vector3 ab = rayEnd - rayStart; Vector3 ab = rayEnd - rayStart;
float ablen = ab.Length();
World.ForEachScenePresence(delegate(ScenePresence sp) World.ForEachScenePresence(delegate(ScenePresence sp)
{ {
Vector3 ac = sp.AbsolutePosition - rayStart; if(skipPhys && sp.PhysicsActor != null)
// Vector3 bc = sp.AbsolutePosition - rayEnd; return;
double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); Vector3 ac = sp.AbsolutePosition - rayStart;
double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / ablen);
if (d > 1.5) if (d > 1.5)
return; return;
@ -14553,8 +14556,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull; RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
if (checkTerrain) if (checkTerrain)
rayfilter |= RayFilterFlags.land; rayfilter |= RayFilterFlags.land;
// if (checkAgents) if (checkAgents)
// rayfilter |= RayFilterFlags.agent; rayfilter |= RayFilterFlags.agent;
if (checkPhysical) if (checkPhysical)
rayfilter |= RayFilterFlags.physical; rayfilter |= RayFilterFlags.physical;
if (checkNonPhysical) if (checkNonPhysical)
@ -14578,18 +14581,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
object physresults; object physresults;
physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter); physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
/*
if (physresults == null) if (physresults == null)
{ {
list.Add(new LSL_Integer(-3)); // timeout error list.Add(new LSL_Integer(-3)); // timeout error
return list; return list;
} }
*/
results = (List<ContactResult>)physresults; results = (List<ContactResult>)physresults;
// for now physics doesn't detect sitted avatars so do it outside physics // for now physics doesn't detect sitted avatars so do it outside physics
if (checkAgents) if (checkAgents)
{ {
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, true);
foreach (ContactResult r in agentHits) foreach (ContactResult r in agentHits)
results.Add(r); results.Add(r);
} }
@ -14610,7 +14614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
if (checkAgents) if (checkAgents)
{ {
ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, false);
foreach (ContactResult r in agentHits) foreach (ContactResult r in agentHits)
results.Add(r); results.Add(r);
} }