From f05a977afaacca2df4406f2d4aefed960a4b7f1c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 16 Apr 2012 16:35:35 +0100 Subject: [PATCH] Let llCastRay use ubitODE raycast if avaiable plus a few changes/fixes that should be checked. PROBLEM: it will not detect nonphysical phantons :( --- .../Shared/Api/Implementation/LSL_Api.cs | 108 ++++++++++++++---- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2f61b70348..5b5e23e038 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11869,38 +11869,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 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); - foreach (ContactResult r in agentHits) - results.Add(r); - } + if (dist == 0) + return list; - 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)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); - foreach (ContactResult r in objectHits) - results.Add(r); + if (checkTerrain) + { + 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) { - return (int)(a.Depth - b.Depth); + return a.Depth.CompareTo(b.Depth); }); int values = 0; + SceneObjectGroup thisgrp = m_host.ParentGroup; + foreach (ContactResult result in results) { if (result.Depth > dist) continue; + // physics ray can return colisions with host prim + if (m_host.LocalId == result.ConsumerID) + continue; + UUID itemID = UUID.Zero; int linkNum = 0; @@ -11908,6 +11971,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // It's a prim! 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) itemID = part.ParentGroup.UUID; else @@ -11918,7 +11985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else { ScenePresence sp = World.GetScenePresence(result.ConsumerID); - /// It it a boy? a girl? + /// It it a boy? a girl? if (sp != null) 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) list.Add(new LSL_Integer(linkNum)); - if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); - - values++; - count--; - if (count == 0) + values++; + if (values >= count) break; }