diff options
Diffstat (limited to 'libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs')
-rw-r--r-- | libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs | 716 |
1 files changed, 358 insertions, 358 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs index 968e219..cb520bb 100644 --- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs +++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs | |||
@@ -1,358 +1,358 @@ | |||
1 | /* | 1 | /* |
2 | Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru | 2 | Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru |
3 | Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com | 3 | Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com |
4 | 4 | ||
5 | This software is provided 'as-is', without any express or implied | 5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages | 6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. | 7 | arising from the use of this software. |
8 | 8 | ||
9 | Permission is granted to anyone to use this software for any purpose, | 9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it | 10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: | 11 | freely, subject to the following restrictions: |
12 | 12 | ||
13 | 1. The origin of this software must not be misrepresented; you must not | 13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software | 14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be | 15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. | 16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be | 17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. | 18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. | 19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | using System; | 22 | using System; |
23 | using System.Collections.Generic; | 23 | using System.Collections.Generic; |
24 | using System.Text; | 24 | using System.Text; |
25 | using MonoXnaCompactMaths; | 25 | using MonoXnaCompactMaths; |
26 | 26 | ||
27 | namespace XnaDevRu.BulletX | 27 | namespace XnaDevRu.BulletX |
28 | { | 28 | { |
29 | public class CollisionWorld | 29 | public class CollisionWorld |
30 | { | 30 | { |
31 | private List<CollisionObject> _collisionObjects = new List<CollisionObject>(); | 31 | private List<CollisionObject> _collisionObjects = new List<CollisionObject>(); |
32 | private IDispatcher _dispatcher; | 32 | private IDispatcher _dispatcher; |
33 | private OverlappingPairCache _broadphasePairCache; | 33 | private OverlappingPairCache _broadphasePairCache; |
34 | private bool _ownsDispatcher; | 34 | private bool _ownsDispatcher; |
35 | private bool _ownsBroadphasePairCache; | 35 | private bool _ownsBroadphasePairCache; |
36 | private DispatcherInfo _dispatchInfo = new DispatcherInfo(); | 36 | private DispatcherInfo _dispatchInfo = new DispatcherInfo(); |
37 | 37 | ||
38 | /// <summary> | 38 | /// <summary> |
39 | /// this constructor doesn't own the dispatcher and paircache/broadphase | 39 | /// this constructor doesn't own the dispatcher and paircache/broadphase |
40 | /// </summary> | 40 | /// </summary> |
41 | /// <param name="dispatcher"></param> | 41 | /// <param name="dispatcher"></param> |
42 | /// <param name="pairCache"></param> | 42 | /// <param name="pairCache"></param> |
43 | public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache) | 43 | public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache) |
44 | { | 44 | { |
45 | _dispatcher = dispatcher; | 45 | _dispatcher = dispatcher; |
46 | _broadphasePairCache = pairCache; | 46 | _broadphasePairCache = pairCache; |
47 | _ownsDispatcher = false; | 47 | _ownsDispatcher = false; |
48 | _ownsBroadphasePairCache = false; | 48 | _ownsBroadphasePairCache = false; |
49 | } | 49 | } |
50 | 50 | ||
51 | public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } } | 51 | public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } } |
52 | public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } } | 52 | public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } } |
53 | public IBroadphase Broadphase { get { return _broadphasePairCache; } } | 53 | public IBroadphase Broadphase { get { return _broadphasePairCache; } } |
54 | public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } } | 54 | public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } } |
55 | public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } } | 55 | public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } } |
56 | public int CollisionObjectsCount { get { return _collisionObjects.Count; } } | 56 | public int CollisionObjectsCount { get { return _collisionObjects.Count; } } |
57 | protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } } | 57 | protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } } |
58 | protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } } | 58 | protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } } |
59 | 59 | ||
60 | // rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback | 60 | // rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback |
61 | // This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. | 61 | // This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. |
62 | public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback) | 62 | public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback) |
63 | { | 63 | { |
64 | Matrix rayFromTrans, rayToTrans; | 64 | Matrix rayFromTrans, rayToTrans; |
65 | 65 | ||
66 | rayFromTrans = Matrix.Identity; | 66 | rayFromTrans = Matrix.Identity; |
67 | rayFromTrans.Translation = rayFromWorld; | 67 | rayFromTrans.Translation = rayFromWorld; |
68 | 68 | ||
69 | rayToTrans = Matrix.Identity; | 69 | rayToTrans = Matrix.Identity; |
70 | rayToTrans.Translation = rayToWorld; | 70 | rayToTrans.Translation = rayToWorld; |
71 | 71 | ||
72 | // brute force go over all objects. Once there is a broadphase, use that, or | 72 | // brute force go over all objects. Once there is a broadphase, use that, or |
73 | // add a raycast against aabb first. | 73 | // add a raycast against aabb first. |
74 | 74 | ||
75 | foreach (CollisionObject collisionObject in _collisionObjects) | 75 | foreach (CollisionObject collisionObject in _collisionObjects) |
76 | { | 76 | { |
77 | //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); | 77 | //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); |
78 | Vector3 collisionObjectAabbMin, collisionObjectAabbMax; | 78 | Vector3 collisionObjectAabbMin, collisionObjectAabbMax; |
79 | collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax); | 79 | collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax); |
80 | 80 | ||
81 | float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing | 81 | float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing |
82 | Vector3 hitNormal = new Vector3(); | 82 | Vector3 hitNormal = new Vector3(); |
83 | 83 | ||
84 | //if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax)) | 84 | //if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax)) |
85 | if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) | 85 | if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) |
86 | { | 86 | { |
87 | RayTestSingle(rayFromTrans, rayToTrans, | 87 | RayTestSingle(rayFromTrans, rayToTrans, |
88 | collisionObject, collisionObject.CollisionShape, | 88 | collisionObject, collisionObject.CollisionShape, |
89 | collisionObject.WorldTransform, resultCallback); | 89 | collisionObject.WorldTransform, resultCallback); |
90 | 90 | ||
91 | } | 91 | } |
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. | 95 | // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. |
96 | // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape. | 96 | // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape. |
97 | // This allows more customization. | 97 | // This allows more customization. |
98 | public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans, | 98 | public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans, |
99 | CollisionObject collisionObject, | 99 | CollisionObject collisionObject, |
100 | CollisionShape collisionShape, | 100 | CollisionShape collisionShape, |
101 | Matrix colObjWorldTransform, | 101 | Matrix colObjWorldTransform, |
102 | RayResultCallback resultCallback) | 102 | RayResultCallback resultCallback) |
103 | { | 103 | { |
104 | SphereShape pointShape=new SphereShape(0.0f); | 104 | SphereShape pointShape=new SphereShape(0.0f); |
105 | 105 | ||
106 | if (collisionShape.IsConvex) | 106 | if (collisionShape.IsConvex) |
107 | { | 107 | { |
108 | CastResult castResult = new CastResult(); | 108 | CastResult castResult = new CastResult(); |
109 | castResult.Fraction = 1f;//?? | 109 | castResult.Fraction = 1f;//?? |
110 | 110 | ||
111 | ConvexShape convexShape = collisionShape as ConvexShape; | 111 | ConvexShape convexShape = collisionShape as ConvexShape; |
112 | VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver(); | 112 | VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver(); |
113 | SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver); | 113 | SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver); |
114 | //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); | 114 | //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); |
115 | //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); | 115 | //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); |
116 | 116 | ||
117 | if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) | 117 | if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) |
118 | { | 118 | { |
119 | //add hit | 119 | //add hit |
120 | if (castResult.Normal.LengthSquared() > 0.0001f) | 120 | if (castResult.Normal.LengthSquared() > 0.0001f) |
121 | { | 121 | { |
122 | castResult.Normal.Normalize(); | 122 | castResult.Normal.Normalize(); |
123 | if (castResult.Fraction < resultCallback.ClosestHitFraction) | 123 | if (castResult.Fraction < resultCallback.ClosestHitFraction) |
124 | { | 124 | { |
125 | 125 | ||
126 | CollisionWorld.LocalRayResult localRayResult = new LocalRayResult | 126 | CollisionWorld.LocalRayResult localRayResult = new LocalRayResult |
127 | ( | 127 | ( |
128 | collisionObject, | 128 | collisionObject, |
129 | new LocalShapeInfo(), | 129 | new LocalShapeInfo(), |
130 | castResult.Normal, | 130 | castResult.Normal, |
131 | castResult.Fraction | 131 | castResult.Fraction |
132 | ); | 132 | ); |
133 | 133 | ||
134 | resultCallback.AddSingleResult(localRayResult); | 134 | resultCallback.AddSingleResult(localRayResult); |
135 | } | 135 | } |
136 | } | 136 | } |
137 | } | 137 | } |
138 | else | 138 | else |
139 | { | 139 | { |
140 | if (collisionShape.IsConcave) | 140 | if (collisionShape.IsConcave) |
141 | { | 141 | { |
142 | 142 | ||
143 | TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape; | 143 | TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape; |
144 | 144 | ||
145 | Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform); | 145 | Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform); |
146 | 146 | ||
147 | Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject); | 147 | Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject); |
148 | Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject); | 148 | Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject); |
149 | 149 | ||
150 | BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh); | 150 | BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh); |
151 | rcb.HitFraction = resultCallback.ClosestHitFraction; | 151 | rcb.HitFraction = resultCallback.ClosestHitFraction; |
152 | 152 | ||
153 | Vector3 rayAabbMinLocal = rayFromLocal; | 153 | Vector3 rayAabbMinLocal = rayFromLocal; |
154 | MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal); | 154 | MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal); |
155 | Vector3 rayAabbMaxLocal = rayFromLocal; | 155 | Vector3 rayAabbMaxLocal = rayFromLocal; |
156 | MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal); | 156 | MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal); |
157 | 157 | ||
158 | triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal); | 158 | triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal); |
159 | } | 159 | } |
160 | else | 160 | else |
161 | { | 161 | { |
162 | //todo: use AABB tree or other BVH acceleration structure! | 162 | //todo: use AABB tree or other BVH acceleration structure! |
163 | if (collisionShape.IsCompound) | 163 | if (collisionShape.IsCompound) |
164 | { | 164 | { |
165 | CompoundShape compoundShape = collisionShape as CompoundShape; | 165 | CompoundShape compoundShape = collisionShape as CompoundShape; |
166 | for (int i = 0; i < compoundShape.ChildShapeCount; i++) | 166 | for (int i = 0; i < compoundShape.ChildShapeCount; i++) |
167 | { | 167 | { |
168 | Matrix childTrans = compoundShape.GetChildTransform(i); | 168 | Matrix childTrans = compoundShape.GetChildTransform(i); |
169 | CollisionShape childCollisionShape = compoundShape.GetChildShape(i); | 169 | CollisionShape childCollisionShape = compoundShape.GetChildShape(i); |
170 | Matrix childWorldTrans = colObjWorldTransform * childTrans; | 170 | Matrix childWorldTrans = colObjWorldTransform * childTrans; |
171 | RayTestSingle(rayFromTrans, rayToTrans, | 171 | RayTestSingle(rayFromTrans, rayToTrans, |
172 | collisionObject, | 172 | collisionObject, |
173 | childCollisionShape, | 173 | childCollisionShape, |
174 | childWorldTrans, | 174 | childWorldTrans, |
175 | resultCallback); | 175 | resultCallback); |
176 | } | 176 | } |
177 | } | 177 | } |
178 | } | 178 | } |
179 | } | 179 | } |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask) | 183 | public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask) |
184 | { | 184 | { |
185 | //check that the object isn't already added | 185 | //check that the object isn't already added |
186 | if (!_collisionObjects.Contains(collisionObject)) | 186 | if (!_collisionObjects.Contains(collisionObject)) |
187 | { | 187 | { |
188 | _collisionObjects.Add(collisionObject); | 188 | _collisionObjects.Add(collisionObject); |
189 | 189 | ||
190 | //calculate new AABB | 190 | //calculate new AABB |
191 | Matrix trans = collisionObject.WorldTransform; | 191 | Matrix trans = collisionObject.WorldTransform; |
192 | 192 | ||
193 | Vector3 minAabb; | 193 | Vector3 minAabb; |
194 | Vector3 maxAabb; | 194 | Vector3 maxAabb; |
195 | collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb); | 195 | collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb); |
196 | 196 | ||
197 | BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType; | 197 | BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType; |
198 | collisionObject.Broadphase = Broadphase.CreateProxy( | 198 | collisionObject.Broadphase = Broadphase.CreateProxy( |
199 | minAabb, | 199 | minAabb, |
200 | maxAabb, | 200 | maxAabb, |
201 | type, | 201 | type, |
202 | collisionObject, | 202 | collisionObject, |
203 | collisionFilterGroup, | 203 | collisionFilterGroup, |
204 | collisionFilterMask | 204 | collisionFilterMask |
205 | ); | 205 | ); |
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | public void AddCollisionObject(CollisionObject collisionObject) | 209 | public void AddCollisionObject(CollisionObject collisionObject) |
210 | { | 210 | { |
211 | AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default); | 211 | AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default); |
212 | } | 212 | } |
213 | 213 | ||
214 | public void RemoveCollisionObject(CollisionObject collisionObject) | 214 | public void RemoveCollisionObject(CollisionObject collisionObject) |
215 | { | 215 | { |
216 | BroadphaseProxy bp = collisionObject.Broadphase; | 216 | BroadphaseProxy bp = collisionObject.Broadphase; |
217 | if (bp != null) | 217 | if (bp != null) |
218 | { | 218 | { |
219 | // | 219 | // |
220 | // only clear the cached algorithms | 220 | // only clear the cached algorithms |
221 | // | 221 | // |
222 | Broadphase.CleanProxyFromPairs(bp); | 222 | Broadphase.CleanProxyFromPairs(bp); |
223 | Broadphase.DestroyProxy(bp); | 223 | Broadphase.DestroyProxy(bp); |
224 | collisionObject.Broadphase = null; | 224 | collisionObject.Broadphase = null; |
225 | } | 225 | } |
226 | 226 | ||
227 | _collisionObjects.Remove(collisionObject); | 227 | _collisionObjects.Remove(collisionObject); |
228 | } | 228 | } |
229 | 229 | ||
230 | public virtual void PerformDiscreteCollisionDetection() | 230 | public virtual void PerformDiscreteCollisionDetection() |
231 | { | 231 | { |
232 | DispatcherInfo dispatchInfo = DispatchInfo; | 232 | DispatcherInfo dispatchInfo = DispatchInfo; |
233 | //update aabb (of all moved objects) | 233 | //update aabb (of all moved objects) |
234 | 234 | ||
235 | Vector3 aabbMin, aabbMax; | 235 | Vector3 aabbMin, aabbMax; |
236 | for (int i = 0; i < _collisionObjects.Count; i++) | 236 | for (int i = 0; i < _collisionObjects.Count; i++) |
237 | { | 237 | { |
238 | _collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax); | 238 | _collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax); |
239 | _broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax); | 239 | _broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax); |
240 | } | 240 | } |
241 | 241 | ||
242 | _broadphasePairCache.RefreshOverlappingPairs(); | 242 | _broadphasePairCache.RefreshOverlappingPairs(); |
243 | 243 | ||
244 | IDispatcher dispatcher = Dispatcher; | 244 | IDispatcher dispatcher = Dispatcher; |
245 | if (dispatcher != null) | 245 | if (dispatcher != null) |
246 | dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo); | 246 | dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo); |
247 | } | 247 | } |
248 | 248 | ||
249 | public void Dispose(bool disposing) | 249 | public void Dispose(bool disposing) |
250 | { | 250 | { |
251 | if (disposing) | 251 | if (disposing) |
252 | { | 252 | { |
253 | //clean up remaining objects | 253 | //clean up remaining objects |
254 | foreach (CollisionObject collisionObject in _collisionObjects) | 254 | foreach (CollisionObject collisionObject in _collisionObjects) |
255 | { | 255 | { |
256 | BroadphaseProxy bp = collisionObject.Broadphase; | 256 | BroadphaseProxy bp = collisionObject.Broadphase; |
257 | if (bp != null) | 257 | if (bp != null) |
258 | { | 258 | { |
259 | // | 259 | // |
260 | // only clear the cached algorithms | 260 | // only clear the cached algorithms |
261 | // | 261 | // |
262 | Broadphase.CleanProxyFromPairs(bp); | 262 | Broadphase.CleanProxyFromPairs(bp); |
263 | Broadphase.DestroyProxy(bp); | 263 | Broadphase.DestroyProxy(bp); |
264 | } | 264 | } |
265 | } | 265 | } |
266 | } | 266 | } |
267 | } | 267 | } |
268 | 268 | ||
269 | /// <summary> | 269 | /// <summary> |
270 | /// LocalShapeInfo gives extra information for complex shapes | 270 | /// LocalShapeInfo gives extra information for complex shapes |
271 | /// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart | 271 | /// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart |
272 | /// </summary> | 272 | /// </summary> |
273 | public struct LocalShapeInfo | 273 | public struct LocalShapeInfo |
274 | { | 274 | { |
275 | private int _shapePart; | 275 | private int _shapePart; |
276 | private int _triangleIndex; | 276 | private int _triangleIndex; |
277 | 277 | ||
278 | public int ShapePart { get { return _shapePart; } set { _shapePart = value; } } | 278 | public int ShapePart { get { return _shapePart; } set { _shapePart = value; } } |
279 | public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } } | 279 | public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } } |
280 | } | 280 | } |
281 | 281 | ||
282 | public struct LocalRayResult | 282 | public struct LocalRayResult |
283 | { | 283 | { |
284 | private CollisionObject _collisionObject; | 284 | private CollisionObject _collisionObject; |
285 | private LocalShapeInfo _localShapeInfo; | 285 | private LocalShapeInfo _localShapeInfo; |
286 | private Vector3 _hitNormalLocal; | 286 | private Vector3 _hitNormalLocal; |
287 | private float _hitFraction; | 287 | private float _hitFraction; |
288 | 288 | ||
289 | public LocalRayResult(CollisionObject collisionObject, | 289 | public LocalRayResult(CollisionObject collisionObject, |
290 | LocalShapeInfo localShapeInfo, | 290 | LocalShapeInfo localShapeInfo, |
291 | Vector3 hitNormalLocal, | 291 | Vector3 hitNormalLocal, |
292 | float hitFraction) | 292 | float hitFraction) |
293 | { | 293 | { |
294 | _collisionObject = collisionObject; | 294 | _collisionObject = collisionObject; |
295 | _localShapeInfo = localShapeInfo; | 295 | _localShapeInfo = localShapeInfo; |
296 | _hitNormalLocal = hitNormalLocal; | 296 | _hitNormalLocal = hitNormalLocal; |
297 | _hitFraction = hitFraction; | 297 | _hitFraction = hitFraction; |
298 | } | 298 | } |
299 | 299 | ||
300 | public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } | 300 | public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } |
301 | public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } } | 301 | public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } } |
302 | public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } } | 302 | public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } } |
303 | public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } } | 303 | public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } } |
304 | } | 304 | } |
305 | 305 | ||
306 | /// <summary> | 306 | /// <summary> |
307 | /// RayResultCallback is used to report new raycast results | 307 | /// RayResultCallback is used to report new raycast results |
308 | /// </summary> | 308 | /// </summary> |
309 | public abstract class RayResultCallback | 309 | public abstract class RayResultCallback |
310 | { | 310 | { |
311 | private float _closestHitFraction; | 311 | private float _closestHitFraction; |
312 | 312 | ||
313 | public RayResultCallback() | 313 | public RayResultCallback() |
314 | { | 314 | { |
315 | _closestHitFraction = 1; | 315 | _closestHitFraction = 1; |
316 | } | 316 | } |
317 | 317 | ||
318 | public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } } | 318 | public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } } |
319 | public bool HasHit { get { return _closestHitFraction < 1; } } | 319 | public bool HasHit { get { return _closestHitFraction < 1; } } |
320 | 320 | ||
321 | public abstract float AddSingleResult(LocalRayResult rayResult); | 321 | public abstract float AddSingleResult(LocalRayResult rayResult); |
322 | } | 322 | } |
323 | 323 | ||
324 | public class ClosestRayResultCallback : RayResultCallback | 324 | public class ClosestRayResultCallback : RayResultCallback |
325 | { | 325 | { |
326 | private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction | 326 | private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction |
327 | private Vector3 _rayToWorld; | 327 | private Vector3 _rayToWorld; |
328 | 328 | ||
329 | private Vector3 _hitNormalWorld; | 329 | private Vector3 _hitNormalWorld; |
330 | private Vector3 _hitPointWorld; | 330 | private Vector3 _hitPointWorld; |
331 | private CollisionObject _collisionObject; | 331 | private CollisionObject _collisionObject; |
332 | 332 | ||
333 | public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld) | 333 | public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld) |
334 | { | 334 | { |
335 | _rayFromWorld = rayFromWorld; | 335 | _rayFromWorld = rayFromWorld; |
336 | _rayToWorld = rayToWorld; | 336 | _rayToWorld = rayToWorld; |
337 | _collisionObject = null; | 337 | _collisionObject = null; |
338 | } | 338 | } |
339 | 339 | ||
340 | public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } } | 340 | public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } } |
341 | public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } } | 341 | public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } } |
342 | public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } } | 342 | public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } } |
343 | public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } } | 343 | public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } } |
344 | public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } | 344 | public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } |
345 | 345 | ||
346 | public override float AddSingleResult(LocalRayResult rayResult) | 346 | public override float AddSingleResult(LocalRayResult rayResult) |
347 | { | 347 | { |
348 | //caller already does the filter on the m_closestHitFraction | 348 | //caller already does the filter on the m_closestHitFraction |
349 | //assert(rayResult.m_hitFraction <= m_closestHitFraction); | 349 | //assert(rayResult.m_hitFraction <= m_closestHitFraction); |
350 | ClosestHitFraction = rayResult.HitFraction; | 350 | ClosestHitFraction = rayResult.HitFraction; |
351 | _collisionObject = rayResult.CollisionObject; | 351 | _collisionObject = rayResult.CollisionObject; |
352 | _hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform); | 352 | _hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform); |
353 | MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld); | 353 | MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld); |
354 | return rayResult.HitFraction; | 354 | return rayResult.HitFraction; |
355 | } | 355 | } |
356 | } | 356 | } |
357 | } | 357 | } |
358 | } | 358 | } |