diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/PhysicsScene.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 90 |
3 files changed, 129 insertions, 13 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5778176..f2cb117 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1983,6 +1983,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1983 | EventManager.TriggerPrimsLoaded(this); | 1983 | EventManager.TriggerPrimsLoaded(this); |
1984 | } | 1984 | } |
1985 | 1985 | ||
1986 | public bool SupportsRayCastFiltered() | ||
1987 | { | ||
1988 | if (PhysicsScene == null) | ||
1989 | return false; | ||
1990 | return PhysicsScene.SupportsRaycastWorldFiltered(); | ||
1991 | } | ||
1992 | |||
1993 | public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | ||
1994 | { | ||
1995 | if (PhysicsScene == null) | ||
1996 | return null; | ||
1997 | return PhysicsScene.RaycastWorld(position, direction, length, Count,filter); | ||
1998 | } | ||
1986 | 1999 | ||
1987 | /// <summary> | 2000 | /// <summary> |
1988 | /// Gets a new rez location based on the raycast and the size of the object that is being rezzed. | 2001 | /// 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 201007b..96a9ff7 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs | |||
@@ -43,6 +43,35 @@ namespace OpenSim.Region.Physics.Manager | |||
43 | public delegate void JointDeactivated(PhysicsJoint joint); | 43 | public delegate void JointDeactivated(PhysicsJoint joint); |
44 | public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" | 44 | public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" |
45 | 45 | ||
46 | public enum RayFilterFlags:ushort | ||
47 | { | ||
48 | // the flags | ||
49 | water = 0x01, | ||
50 | land = 0x02, | ||
51 | agent = 0x04, | ||
52 | nonphysical = 0x08, | ||
53 | physical = 0x10, | ||
54 | phantom = 0x20, | ||
55 | volumedtc = 0x40, | ||
56 | |||
57 | // ray cast colision control (may only work for meshs) | ||
58 | ContactsUnImportant = 0x2000, | ||
59 | BackFaceCull = 0x4000, | ||
60 | ClosestHit = 0x8000, | ||
61 | |||
62 | // some combinations | ||
63 | LSLPhanton = phantom | volumedtc, | ||
64 | PrimsNonPhantom = nonphysical | physical, | ||
65 | PrimsNonPhantomAgents = nonphysical | physical | agent, | ||
66 | |||
67 | AllPrims = nonphysical | phantom | volumedtc | physical, | ||
68 | AllButLand = agent | nonphysical | physical | phantom | volumedtc, | ||
69 | |||
70 | ClosestAndBackCull = ClosestHit | BackFaceCull, | ||
71 | |||
72 | All = 0x3f | ||
73 | } | ||
74 | |||
46 | public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback); | 75 | public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback); |
47 | public delegate void AssetReceivedDelegate(AssetBase asset); | 76 | public delegate void AssetReceivedDelegate(AssetBase asset); |
48 | 77 | ||
@@ -286,5 +315,15 @@ namespace OpenSim.Region.Physics.Manager | |||
286 | { | 315 | { |
287 | return new List<ContactResult>(); | 316 | return new List<ContactResult>(); |
288 | } | 317 | } |
318 | |||
319 | public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | ||
320 | { | ||
321 | return null; | ||
322 | } | ||
323 | |||
324 | public virtual bool SupportsRaycastWorldFiltered() | ||
325 | { | ||
326 | return false; | ||
327 | } | ||
289 | } | 328 | } |
290 | } | 329 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 632b73f..3a7e1c7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -11340,25 +11340,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11340 | bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); | 11340 | bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); |
11341 | 11341 | ||
11342 | 11342 | ||
11343 | if (checkTerrain) | 11343 | if (World.SupportsRayCastFiltered()) |
11344 | { | 11344 | { |
11345 | ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); | 11345 | if (dist == 0) |
11346 | if (groundContact != null) | 11346 | return list; |
11347 | results.Add((ContactResult)groundContact); | 11347 | |
11348 | } | 11348 | RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; |
11349 | if (checkTerrain) | ||
11350 | rayfilter |= RayFilterFlags.land; | ||
11351 | // if (checkAgents) | ||
11352 | // rayfilter |= RayFilterFlags.agent; | ||
11353 | if (checkPhysical) | ||
11354 | rayfilter |= RayFilterFlags.physical; | ||
11355 | if (checkNonPhysical) | ||
11356 | rayfilter |= RayFilterFlags.nonphysical; | ||
11357 | if (detectPhantom) | ||
11358 | rayfilter |= RayFilterFlags.LSLPhanton; | ||
11359 | |||
11360 | Vector3 direction = dir * ( 1/dist); | ||
11361 | |||
11362 | if(rayfilter == 0) | ||
11363 | { | ||
11364 | list.Add(new LSL_Integer(0)); | ||
11365 | return list; | ||
11366 | } | ||
11367 | |||
11368 | // get some more contacts to sort ??? | ||
11369 | int physcount = 4 * count; | ||
11370 | if (physcount > 20) | ||
11371 | physcount = 20; | ||
11372 | |||
11373 | object physresults; | ||
11374 | physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter); | ||
11375 | |||
11376 | if (physresults == null) | ||
11377 | { | ||
11378 | list.Add(new LSL_Integer(-3)); // timeout error | ||
11379 | return list; | ||
11380 | } | ||
11381 | |||
11382 | results = (List<ContactResult>)physresults; | ||
11349 | 11383 | ||
11350 | if (checkAgents) | 11384 | // for now physics doesn't detect sitted avatars so do it outside physics |
11385 | if (checkAgents) | ||
11386 | { | ||
11387 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); | ||
11388 | foreach (ContactResult r in agentHits) | ||
11389 | results.Add(r); | ||
11390 | } | ||
11391 | |||
11392 | // TODO: Replace this with a better solution. ObjectIntersection can only | ||
11393 | // detect nonphysical phantoms. They are detected by virtue of being | ||
11394 | // nonphysical (e.g. no PhysActor) so will not conflict with detecting | ||
11395 | // physicsl phantoms as done by the physics scene | ||
11396 | // We don't want anything else but phantoms here. | ||
11397 | if (detectPhantom) | ||
11398 | { | ||
11399 | ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true); | ||
11400 | foreach (ContactResult r in objectHits) | ||
11401 | results.Add(r); | ||
11402 | } | ||
11403 | } | ||
11404 | else | ||
11351 | { | 11405 | { |
11352 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); | 11406 | if (checkAgents) |
11353 | foreach (ContactResult r in agentHits) | 11407 | { |
11354 | results.Add(r); | 11408 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); |
11409 | foreach (ContactResult r in agentHits) | ||
11410 | results.Add(r); | ||
11411 | } | ||
11412 | |||
11413 | if (checkPhysical || checkNonPhysical || detectPhantom) | ||
11414 | { | ||
11415 | ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); | ||
11416 | foreach (ContactResult r in objectHits) | ||
11417 | results.Add(r); | ||
11418 | } | ||
11355 | } | 11419 | } |
11356 | 11420 | ||
11357 | if (checkPhysical || checkNonPhysical || detectPhantom) | 11421 | if (checkTerrain) |
11358 | { | 11422 | { |
11359 | ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); | 11423 | ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); |
11360 | foreach (ContactResult r in objectHits) | 11424 | if (groundContact != null) |
11361 | results.Add(r); | 11425 | results.Add((ContactResult)groundContact); |
11362 | } | 11426 | } |
11363 | 11427 | ||
11364 | results.Sort(delegate(ContactResult a, ContactResult b) | 11428 | results.Sort(delegate(ContactResult a, ContactResult b) |