diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionDispatcher.cs | 280 |
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 | |||
22 | using System; | ||
23 | using System.Collections.Generic; | ||
24 | using System.Text; | ||
25 | using MonoXnaCompactMaths; | ||
26 | |||
27 | namespace 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 | } | ||