From c1795ed399c187ba739bc271c6837e26b9bfdf3d Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 21:03:24 +0000 Subject: [PATCH] Add the Avination physics raycast glue so Core Physics can implement raycast --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++ .../Region/Physics/Manager/PhysicsScene.cs | 39 ++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 92 ++++++++++++++++--- 3 files changed, 130 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5778176e44..f2cb117683 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1983,6 +1983,19 @@ namespace OpenSim.Region.Framework.Scenes 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); + } /// /// Gets a new rez location based on the raycast and the size of the object that is being rezzed. diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 201007bdec..96a9ff7ea0 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -43,6 +43,35 @@ namespace OpenSim.Region.Physics.Manager 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 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 AssetReceivedDelegate(AssetBase asset); @@ -286,5 +315,15 @@ namespace OpenSim.Region.Physics.Manager { return new List(); } + + public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) + { + return null; + } + + public virtual bool SupportsRaycastWorldFiltered() + { + return false; + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 632b73f2bd..3a7e1c7dc8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11340,6 +11340,84 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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)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) { ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); @@ -11347,20 +11425,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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 a.Depth.CompareTo(b.Depth);