aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs280
1 files changed, 280 insertions, 0 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs
new file mode 100644
index 0000000..75d35b0
--- /dev/null
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs
@@ -0,0 +1,280 @@
1/*
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
4
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
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
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
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using MonoXnaCompactMaths;
26
27namespace XnaDevRu.BulletX
28{
29 public delegate void NearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo);
30
31 public class CollisionDispatcher : IDispatcher
32 {
33 private List<PersistentManifold> _manifolds = new List<PersistentManifold>();
34
35 //private bool _useIslands;
36 private NearCallback _nearCallback;
37
38 //private ManifoldResult _defaultManifoldResult;
39
40 private CollisionAlgorithmCreateFunction[,] _doubleDispatch = new CollisionAlgorithmCreateFunction[(int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes, (int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes];
41
42 //default CreationFunctions, filling the m_doubleDispatch table
43 private CollisionAlgorithmCreateFunction _convexConvexCreateFunc;
44 private CollisionAlgorithmCreateFunction _convexConcaveCreateFunc;
45 private CollisionAlgorithmCreateFunction _swappedConvexConcaveCreateFunc;
46 private CollisionAlgorithmCreateFunction _compoundCreateFunc;
47 private CollisionAlgorithmCreateFunction _swappedCompoundCreateFunc;
48 private CollisionAlgorithmCreateFunction _emptyCreateFunc;
49
50 private int _count;
51 private static int _manifoldCount = 0;
52
53 public CollisionDispatcher()
54 {
55 NearCallback = DefaultNearCallback;
56 //_useIslands = true;
57 //default CreationFunctions, filling the m_doubleDispatch table
58 _convexConvexCreateFunc = new ConvexConvexAlgorithm.CreateFunc();
59 _convexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.CreateFunc();
60 _swappedConvexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.SwappedCreateFunc();
61 _compoundCreateFunc = new CompoundCollisionAlgorithm.CreateFunc();
62 _swappedCompoundCreateFunc = new CompoundCollisionAlgorithm.SwappedCreateFunc();
63 _emptyCreateFunc = new EmptyAlgorithm.CreateFunc();
64
65 for (BroadphaseNativeTypes i = BroadphaseNativeTypes.Box; i < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; i++)
66 {
67 for (BroadphaseNativeTypes j = BroadphaseNativeTypes.Box; j < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; j++)
68 {
69 _doubleDispatch[(int)i, (int)j] = FindCreateFunction(i, j);
70 if (_doubleDispatch[(int)i, (int)j] == null)
71 throw new BulletException();
72 }
73 }
74 }
75
76 public int Count { get { return _count; } set { _count = value; } }
77 public int ManifoldCount { get { return _manifolds.Count; } }
78 public List<PersistentManifold> Manifolds { get { return _manifolds; } }
79
80 public static int GlobalManifoldCount { get { return _manifoldCount; } set { _manifoldCount = value; } }
81
82 public PersistentManifold GetManifoldByIndex(int index)
83 {
84 return _manifolds[index];
85 }
86
87 //registerCollisionCreateFunc allows registration of custom/alternative collision create functions
88 public void RegisterCollisionCreateFunc(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB, CollisionAlgorithmCreateFunction createFunc)
89 {
90 _doubleDispatch[(int)proxyTypeA, (int)proxyTypeB] = createFunc;
91 }
92
93 public virtual PersistentManifold GetNewManifold(object bodyA, object bodyB)
94 {
95 _manifoldCount++;
96
97 CollisionObject body0 = bodyA as CollisionObject;
98 CollisionObject body1 = bodyB as CollisionObject;
99
100 PersistentManifold manifold = new PersistentManifold(body0, body1);
101 _manifolds.Add(manifold);
102
103 return manifold;
104 }
105
106 public virtual void ReleaseManifold(PersistentManifold manifold)
107 {
108 _manifoldCount--;
109
110 ClearManifold(manifold);
111 _manifolds.Remove(manifold);
112 }
113
114
115 public virtual void ClearManifold(PersistentManifold manifold)
116 {
117 manifold.ClearManifold();
118 }
119
120 public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB)
121 {
122 return FindAlgorithm(bodyA, bodyB, null);
123 }
124
125 public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold)
126 {
127 CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
128 collisionAlgorithmConstructionInfo.Dispatcher = this;
129 collisionAlgorithmConstructionInfo.Manifold = sharedManifold;
130 CollisionAlgorithm collisionAlgorithm = _doubleDispatch[(int)bodyA.CollisionShape.ShapeType, (int)bodyB.CollisionShape.ShapeType].CreateCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB);
131 return collisionAlgorithm;
132 }
133
134 /*public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1)
135 {
136 return internalFindAlgorithm(body0, body1, null);
137 }
138
139 public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1, PersistentManifold sharedManifold)
140 {
141 m_count++;
142
143 CollisionAlgorithmConstructionInfo ci = new CollisionAlgorithmConstructionInfo();
144 ci.m_dispatcher = this;
145
146 if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConvex())
147 {
148 return new ConvexConvexAlgorithm(sharedManifold, ci, body0, body1);
149 }
150
151 if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConcave())
152 {
153 return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, false);
154 }
155
156 if (body1.getCollisionShape().isConvex() && body0.getCollisionShape().isConcave())
157 {
158 return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, true);
159 }
160
161 if (body0.getCollisionShape().isCompound())
162 {
163 return new CompoundCollisionAlgorithm(ci, body0, body1, false);
164 }
165 else
166 {
167 if (body1.getCollisionShape().isCompound())
168 {
169 return new CompoundCollisionAlgorithm(ci, body0, body1, true);
170 }
171 }
172
173 //failed to find an algorithm
174 return new EmptyAlgorithm(ci);
175 }*/
176
177 public virtual bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
178 {
179 if (bodyA == null || bodyB == null)
180 throw new BulletException();
181
182 bool needsCollision = true;
183
184 //broadphase filtering already deals with this
185 /*if ((body0.isStaticObject() || body0.isKinematicObject()) &&
186 (body1.isStaticObject() || body1.isKinematicObject()))
187 {
188 printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
189 }*/
190
191 if ((!bodyA.IsActive) && (!bodyB.IsActive))
192 needsCollision = false;
193
194 return needsCollision;
195 }
196
197 public virtual bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB)
198 {
199 //here you can do filtering
200 bool hasResponse = bodyA.HasContactResponse && bodyB.HasContactResponse;
201 hasResponse = hasResponse && (!bodyA.IsStaticOrKinematicObject || !bodyB.IsStaticOrKinematicObject);
202 return hasResponse;
203 }
204
205 public virtual void DispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo)
206 {
207 CollisionPairCallback collisionCallback = new CollisionPairCallback(dispatchInfo, this);
208 pairCache.ProcessAllOverlappingPairs(collisionCallback);
209 }
210
211 private CollisionAlgorithmCreateFunction FindCreateFunction(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB)
212 {
213 if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConvex(proxyTypeB))
214 {
215 return _convexConvexCreateFunc;
216 }
217
218 if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConcave(proxyTypeB))
219 {
220 return _convexConcaveCreateFunc;
221 }
222
223 if (BroadphaseProxy.IsConvex(proxyTypeB) && BroadphaseProxy.IsConcave(proxyTypeA))
224 {
225 return _swappedConvexConcaveCreateFunc;
226 }
227
228 if (BroadphaseProxy.IsCompound(proxyTypeA))
229 {
230 return _compoundCreateFunc;
231 }
232 else
233 {
234 if (BroadphaseProxy.IsCompound(proxyTypeB))
235 {
236 return _swappedCompoundCreateFunc;
237 }
238 }
239
240 //failed to find an algorithm
241 return _emptyCreateFunc;
242 }
243
244 public NearCallback NearCallback { get { return _nearCallback; } set { _nearCallback = value; } }
245
246 //by default, Bullet will use this near callback
247 public static void DefaultNearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo)
248 {
249 CollisionObject collisionObjectA = collisionPair.ProxyA.ClientData as CollisionObject;
250 CollisionObject collisionObjectB = collisionPair.ProxyB.ClientData as CollisionObject;
251
252 if (dispatcher.NeedsCollision(collisionObjectA, collisionObjectB))
253 {
254 //dispatcher will keep algorithms persistent in the collision pair
255 if (collisionPair.CollisionAlgorithm == null)
256 {
257 collisionPair.CollisionAlgorithm = dispatcher.FindAlgorithm(collisionObjectA, collisionObjectB);
258 }
259
260 if (collisionPair.CollisionAlgorithm != null)
261 {
262 ManifoldResult contactPointResult = new ManifoldResult(collisionObjectA, collisionObjectB);
263
264 if (dispatchInfo.DispatchFunction == DispatchFunction.Discrete)
265 {
266 //discrete collision detection query
267 collisionPair.CollisionAlgorithm.ProcessCollision(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
268 }
269 else
270 {
271 //continuous collision detection query, time of impact (toi)
272 float timeOfImpact = collisionPair.CollisionAlgorithm.CalculateTimeOfImpact(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
273 if (dispatchInfo.TimeOfImpact > timeOfImpact)
274 dispatchInfo.TimeOfImpact = timeOfImpact;
275 }
276 }
277 }
278 }
279 }
280}