diff options
author | Robert Adams | 2017-09-02 13:06:36 -0700 |
---|---|---|
committer | Robert Adams | 2017-09-02 13:06:36 -0700 |
commit | 0afa3a294ab36382cf720e9cceb9211a83fbf101 (patch) | |
tree | 5e5c1c62be9880052a2cab1a33055017d2d868bd /OpenSim/Region | |
parent | fix cache.cs (used on parcels info) (diff) | |
download | opensim-SC-0afa3a294ab36382cf720e9cceb9211a83fbf101.zip opensim-SC-0afa3a294ab36382cf720e9cceb9211a83fbf101.tar.gz opensim-SC-0afa3a294ab36382cf720e9cceb9211a83fbf101.tar.bz2 opensim-SC-0afa3a294ab36382cf720e9cceb9211a83fbf101.tar.xz |
BulletSim: most of the plumbing for raycast. Needs new BulletSim.dll to
work.
Diffstat (limited to 'OpenSim/Region')
8 files changed, 252 insertions, 0 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs index 42db7fe..840e453 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs | |||
@@ -1405,6 +1405,19 @@ public override float GetMargin(BulletShape shape) | |||
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | // ===================================================================================== | 1407 | // ===================================================================================== |
1408 | // Raycast | ||
1409 | public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody sweepObject, Vector3 from, Vector3 to, float margin) { | ||
1410 | BulletWorldUnman worldu = world as BulletWorldUnman; | ||
1411 | BulletBodyUnman bodyu = sweepObject as BulletBodyUnman; | ||
1412 | return BSAPICPP.ConvexSweepTest2(worldu.ptr, bodyu.ptr, from, to, margin); | ||
1413 | } | ||
1414 | |||
1415 | public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) { | ||
1416 | BulletWorldUnman worldu = world as BulletWorldUnman; | ||
1417 | return BSAPICPP.RayTest2(worldu.ptr, from, to, filterGroup, filterMask); | ||
1418 | } | ||
1419 | |||
1420 | // ===================================================================================== | ||
1408 | // Debugging | 1421 | // Debugging |
1409 | public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) | 1422 | public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) |
1410 | { | 1423 | { |
@@ -2084,6 +2097,15 @@ public static extern void SetMargin2(IntPtr shape, float val); | |||
2084 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 2097 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
2085 | public static extern float GetMargin2(IntPtr shape); | 2098 | public static extern float GetMargin2(IntPtr shape); |
2086 | 2099 | ||
2100 | |||
2101 | // ===================================================================================== | ||
2102 | // Raycast | ||
2103 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
2104 | public static extern SweepHit ConvexSweepTest2(IntPtr sim, IntPtr obj, Vector3 from, Vector3 to, float margin); | ||
2105 | |||
2106 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
2107 | public static extern RaycastHit RayTest2(IntPtr sim, Vector3 from, Vector3 to, uint filterGroup, uint filterMask); | ||
2108 | |||
2087 | // ===================================================================================== | 2109 | // ===================================================================================== |
2088 | // Debugging | 2110 | // Debugging |
2089 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 2111 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs index 37017b0..7d58728 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs | |||
@@ -2459,6 +2459,14 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
2459 | } | 2459 | } |
2460 | return false; | 2460 | return false; |
2461 | } | 2461 | } |
2462 | |||
2463 | public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin) { | ||
2464 | return new SweepHit(); | ||
2465 | } | ||
2466 | |||
2467 | public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) { | ||
2468 | return new RaycastHit(); | ||
2469 | } | ||
2462 | } | 2470 | } |
2463 | 2471 | ||
2464 | 2472 | ||
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs index 816189f..afb0ba2 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs | |||
@@ -128,6 +128,7 @@ public struct RaycastHit | |||
128 | public UInt32 ID; | 128 | public UInt32 ID; |
129 | public float Fraction; | 129 | public float Fraction; |
130 | public Vector3 Normal; | 130 | public Vector3 Normal; |
131 | public Vector3 Point; | ||
131 | } | 132 | } |
132 | [StructLayout(LayoutKind.Sequential)] | 133 | [StructLayout(LayoutKind.Sequential)] |
133 | public struct CollisionDesc | 134 | public struct CollisionDesc |
@@ -742,6 +743,12 @@ public abstract void SetMargin(BulletShape shape, float val); | |||
742 | public abstract float GetMargin(BulletShape shape); | 743 | public abstract float GetMargin(BulletShape shape); |
743 | 744 | ||
744 | // ===================================================================================== | 745 | // ===================================================================================== |
746 | // Raycast | ||
747 | public abstract SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin); | ||
748 | |||
749 | public abstract RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask); | ||
750 | |||
751 | // ===================================================================================== | ||
745 | // Debugging | 752 | // Debugging |
746 | public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } | 753 | public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } |
747 | 754 | ||
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs index 953ddee..dc390b2 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs | |||
@@ -450,6 +450,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
450 | m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); | 450 | m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); |
451 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", | 451 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", |
452 | LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); | 452 | LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); |
453 | m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG | ||
453 | 454 | ||
454 | // With all of the linkset packed into the root prim, it has the mass of everyone. | 455 | // With all of the linkset packed into the root prim, it has the mass of everyone. |
455 | LinksetMass = ComputeLinksetMass(); | 456 | LinksetMass = ComputeLinksetMass(); |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 352c03e..0792f5d 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | |||
@@ -230,6 +230,8 @@ public static class BSParam | |||
230 | public static float LinkConstraintCFM { get; private set; } | 230 | public static float LinkConstraintCFM { get; private set; } |
231 | public static float LinkConstraintSolverIterations { get; private set; } | 231 | public static float LinkConstraintSolverIterations { get; private set; } |
232 | 232 | ||
233 | public static bool UseBulletRaycast { get; private set; } | ||
234 | |||
233 | public static float PID_D { get; private set; } // derivative | 235 | public static float PID_D { get; private set; } // derivative |
234 | public static float PID_P { get; private set; } // proportional | 236 | public static float PID_P { get; private set; } // proportional |
235 | 237 | ||
@@ -823,6 +825,9 @@ public static class BSParam | |||
823 | new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", | 825 | new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", |
824 | 40 ), | 826 | 40 ), |
825 | 827 | ||
828 | new ParameterDefn<bool>("UseBulletRaycast", "If 'true', use the raycast function of the Bullet physics engine", | ||
829 | true ), | ||
830 | |||
826 | new ParameterDefn<float>("DebugNumber", "A console setable number sometimes used for debugging", | 831 | new ParameterDefn<float>("DebugNumber", "A console setable number sometimes used for debugging", |
827 | 1.0f ), | 832 | 1.0f ), |
828 | 833 | ||
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs index 7ff0a07..f1ff3a9 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | |||
@@ -956,6 +956,98 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
956 | 956 | ||
957 | #endregion // Terrain | 957 | #endregion // Terrain |
958 | 958 | ||
959 | #region Raycast | ||
960 | |||
961 | public override bool SupportsRayCast() | ||
962 | { | ||
963 | return BSParam.UseBulletRaycast; | ||
964 | } | ||
965 | |||
966 | public override bool SupportsRaycastWorldFiltered() | ||
967 | { | ||
968 | return BSParam.UseBulletRaycast; | ||
969 | } | ||
970 | |||
971 | |||
972 | /// <summary> | ||
973 | /// Queue a raycast against the physics scene. | ||
974 | /// The provided callback method will be called when the raycast is complete | ||
975 | /// | ||
976 | /// Many physics engines don't support collision testing at the same time as | ||
977 | /// manipulating the physics scene, so we queue the request up and callback | ||
978 | /// a custom method when the raycast is complete. | ||
979 | /// This allows physics engines that give an immediate result to callback immediately | ||
980 | /// and ones that don't, to callback when it gets a result back. | ||
981 | /// public delegate void RayCallback(List<ContactResult> list); | ||
982 | /// | ||
983 | /// ODE for example will not allow you to change the scene while collision testing or | ||
984 | /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene. | ||
985 | /// | ||
986 | /// This is named RayCastWorld to not conflict with modrex's Raycast method. | ||
987 | /// </summary> | ||
988 | /// <param name="position">Origin of the ray</param> | ||
989 | /// <param name="direction">Direction of the ray</param> | ||
990 | /// <param name="length">Length of ray in meters</param> | ||
991 | /// <param name="retMethod">Method to call when the raycast is complete</param> | ||
992 | public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | ||
993 | { | ||
994 | if (retMethod != null) | ||
995 | { | ||
996 | if (BSParam.UseBulletRaycast) | ||
997 | { | ||
998 | Vector3 posFrom = position; | ||
999 | Vector3 posTo = Vector3.Normalize(direction) * length + position; | ||
1000 | |||
1001 | TaintedObject(DetailLogZero, "BSScene.RaycastWorld1", delegate () | ||
1002 | { | ||
1003 | RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff); | ||
1004 | retMethod(true, hitInfo.Point, hitInfo.ID, hitInfo.Fraction, hitInfo.Normal); | ||
1005 | }); | ||
1006 | } | ||
1007 | else | ||
1008 | { | ||
1009 | retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); | ||
1010 | } | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) | ||
1015 | { | ||
1016 | if (retMethod != null) | ||
1017 | { | ||
1018 | if (BSParam.UseBulletRaycast) | ||
1019 | { | ||
1020 | List<ContactResult> hitInfo = RaycastWorld(position, direction, length, count); | ||
1021 | retMethod(hitInfo); | ||
1022 | } | ||
1023 | else | ||
1024 | { | ||
1025 | retMethod(new List<ContactResult>()); | ||
1026 | } | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1030 | public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) | ||
1031 | { | ||
1032 | List<ContactResult> ret = new List<ContactResult>(); | ||
1033 | if (BSParam.UseBulletRaycast) | ||
1034 | { | ||
1035 | } | ||
1036 | return ret; | ||
1037 | } | ||
1038 | |||
1039 | public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | ||
1040 | { | ||
1041 | object ret = null; | ||
1042 | if (BSParam.UseBulletRaycast) | ||
1043 | { | ||
1044 | } | ||
1045 | return ret; | ||
1046 | } | ||
1047 | |||
1048 | #endregion Raycast | ||
1049 | |||
1050 | |||
959 | public override Dictionary<uint, float> GetTopColliders() | 1051 | public override Dictionary<uint, float> GetTopColliders() |
960 | { | 1052 | { |
961 | Dictionary<uint, float> topColliders; | 1053 | Dictionary<uint, float> topColliders; |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs index 4ec6f51..cd72c98 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs | |||
@@ -229,6 +229,8 @@ public sealed class BSShapeCollection : IDisposable | |||
229 | ret = CreateGeomMeshOrHull(prim, shapeCallback); | 229 | ret = CreateGeomMeshOrHull(prim, shapeCallback); |
230 | } | 230 | } |
231 | 231 | ||
232 | m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG | ||
233 | |||
232 | return ret; | 234 | return ret; |
233 | } | 235 | } |
234 | 236 | ||
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs new file mode 100755 index 0000000..046df56 --- /dev/null +++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | using NUnit.Framework; | ||
34 | using log4net; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.PhysicsModule.BulletS; | ||
38 | using OpenSim.Region.PhysicsModules.SharedBase; | ||
39 | using OpenSim.Tests.Common; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | |||
43 | namespace OpenSim.Region.PhysicsModule.BulletS.Tests | ||
44 | { | ||
45 | [TestFixture] | ||
46 | public class BulletSimRaycast : OpenSimTestCase | ||
47 | { | ||
48 | // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 | ||
49 | // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 | ||
50 | |||
51 | BSScene PhysicsScene { get; set; } | ||
52 | BSPrim TargetSphere { get; set; } | ||
53 | Vector3 TargetSpherePosition { get; set; } | ||
54 | float simulationTimeStep = 0.089f; | ||
55 | |||
56 | [TestFixtureSetUp] | ||
57 | public void Init() | ||
58 | { | ||
59 | Dictionary<string, string> engineParams = new Dictionary<string, string>(); | ||
60 | engineParams.Add("UseBulletRaycast", "true"); | ||
61 | PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); | ||
62 | |||
63 | PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); | ||
64 | Vector3 pos = new Vector3(100.0f, 100.0f, 50f); | ||
65 | pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f; | ||
66 | TargetSpherePosition = pos; | ||
67 | Vector3 size = new Vector3(10f, 10f, 10f); | ||
68 | pbs.Scale = size; | ||
69 | Quaternion rot = Quaternion.Identity; | ||
70 | bool isPhys = false; | ||
71 | uint localID = 123; | ||
72 | |||
73 | PhysicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, localID); | ||
74 | TargetSphere = (BSPrim)PhysicsScene.PhysObjects[localID]; | ||
75 | // The actual prim shape creation happens at taint time | ||
76 | PhysicsScene.ProcessTaints(); | ||
77 | |||
78 | } | ||
79 | |||
80 | [TestFixtureTearDown] | ||
81 | public void TearDown() | ||
82 | { | ||
83 | if (PhysicsScene != null) | ||
84 | { | ||
85 | // The Dispose() will also free any physical objects in the scene | ||
86 | PhysicsScene.Dispose(); | ||
87 | PhysicsScene = null; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | // There is a 10x10x10 sphere at <100,100,50> | ||
92 | // Shoot rays around the sphere and verify it hits and doesn't hit | ||
93 | // TestCase parameters are <x,y,z> of start and <x,y,z> of end and expected result | ||
94 | [TestCase(20f, 20f, 50f, 50f, 50f, 50f, true)] // in front to sphere | ||
95 | [TestCase(20f, 20f, 100f, 50f, 50f, 50f, true)] // from above to sphere | ||
96 | [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true)] // through sphere | ||
97 | [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false)] // pass over sphere | ||
98 | public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected) { | ||
99 | Vector3 fromPos = new Vector3(fromX, fromY, fromZ); | ||
100 | Vector3 toPos = new Vector3(toX, toY, toZ); | ||
101 | Vector3 direction = toPos - fromPos; | ||
102 | float len = Vector3.Distance(fromPos, toPos); | ||
103 | |||
104 | List<ContactResult> results = PhysicsScene.RaycastWorld(fromPos, direction, len, 1); | ||
105 | |||
106 | if (expected) { | ||
107 | Assert.True(results.Count > 0); | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | Assert.False(results.Count > 0); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } \ No newline at end of file | ||