1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 #include "btDefaultCollisionConfiguration.h"
17 
18 #include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
19 #include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
20 #include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
21 #include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
22 #include "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h"
23 
24 #include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
25 #include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
26 #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
27 #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
28 #include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
29 #endif  //USE_BUGGY_SPHERE_BOX_ALGORITHM
30 #include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
31 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
32 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
33 #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
34 
35 #include "LinearMath/btPoolAllocator.h"
36 
btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo & constructionInfo)37 btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
38 //btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc*	stackAlloc,btPoolAllocator*	persistentManifoldPool,btPoolAllocator*	collisionAlgorithmPool)
39 {
40 	void* mem = NULL;
41 	if (constructionInfo.m_useEpaPenetrationAlgorithm)
42 	{
43 		mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver), 16);
44 		m_pdSolver = new (mem) btGjkEpaPenetrationDepthSolver;
45 	}
46 	else
47 	{
48 		mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver), 16);
49 		m_pdSolver = new (mem) btMinkowskiPenetrationDepthSolver;
50 	}
51 
52 	//default CreationFunctions, filling the m_doubleDispatch table
53 	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc), 16);
54 	m_convexConvexCreateFunc = new (mem) btConvexConvexAlgorithm::CreateFunc(m_pdSolver);
55 	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc), 16);
56 	m_convexConcaveCreateFunc = new (mem) btConvexConcaveCollisionAlgorithm::CreateFunc;
57 	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc), 16);
58 	m_swappedConvexConcaveCreateFunc = new (mem) btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
59 	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc), 16);
60 	m_compoundCreateFunc = new (mem) btCompoundCollisionAlgorithm::CreateFunc;
61 
62 	mem = btAlignedAlloc(sizeof(btCompoundCompoundCollisionAlgorithm::CreateFunc), 16);
63 	m_compoundCompoundCreateFunc = new (mem) btCompoundCompoundCollisionAlgorithm::CreateFunc;
64 
65 	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc), 16);
66 	m_swappedCompoundCreateFunc = new (mem) btCompoundCollisionAlgorithm::SwappedCreateFunc;
67 	mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc), 16);
68 	m_emptyCreateFunc = new (mem) btEmptyAlgorithm::CreateFunc;
69 
70 	mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc), 16);
71 	m_sphereSphereCF = new (mem) btSphereSphereCollisionAlgorithm::CreateFunc;
72 #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
73 	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc), 16);
74 	m_sphereBoxCF = new (mem) btSphereBoxCollisionAlgorithm::CreateFunc;
75 	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc), 16);
76 	m_boxSphereCF = new (mem) btSphereBoxCollisionAlgorithm::CreateFunc;
77 	m_boxSphereCF->m_swapped = true;
78 #endif  //USE_BUGGY_SPHERE_BOX_ALGORITHM
79 
80 	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc), 16);
81 	m_sphereTriangleCF = new (mem) btSphereTriangleCollisionAlgorithm::CreateFunc;
82 	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc), 16);
83 	m_triangleSphereCF = new (mem) btSphereTriangleCollisionAlgorithm::CreateFunc;
84 	m_triangleSphereCF->m_swapped = true;
85 
86 	mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc), 16);
87 	m_boxBoxCF = new (mem) btBoxBoxCollisionAlgorithm::CreateFunc;
88 
89 	//convex versus plane
90 	mem = btAlignedAlloc(sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc), 16);
91 	m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
92 	mem = btAlignedAlloc(sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc), 16);
93 	m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
94 	m_planeConvexCF->m_swapped = true;
95 
96 	///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
97 	int maxSize = sizeof(btConvexConvexAlgorithm);
98 	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
99 	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
100 	int maxSize4 = sizeof(btCompoundCompoundCollisionAlgorithm);
101 
102 	int collisionAlgorithmMaxElementSize = btMax(maxSize, constructionInfo.m_customCollisionAlgorithmMaxElementSize);
103 	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize2);
104 	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize3);
105 	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize4);
106 
107 	if (constructionInfo.m_persistentManifoldPool)
108 	{
109 		m_ownsPersistentManifoldPool = false;
110 		m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
111 	}
112 	else
113 	{
114 		m_ownsPersistentManifoldPool = true;
115 		void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16);
116 		m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold), constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
117 	}
118 
119 	collisionAlgorithmMaxElementSize = (collisionAlgorithmMaxElementSize + 16) & 0xffffffffffff0;
120 	if (constructionInfo.m_collisionAlgorithmPool)
121 	{
122 		m_ownsCollisionAlgorithmPool = false;
123 		m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
124 	}
125 	else
126 	{
127 		m_ownsCollisionAlgorithmPool = true;
128 		void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16);
129 		m_collisionAlgorithmPool = new (mem) btPoolAllocator(collisionAlgorithmMaxElementSize, constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
130 	}
131 }
132 
~btDefaultCollisionConfiguration()133 btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
134 {
135 	if (m_ownsCollisionAlgorithmPool)
136 	{
137 		m_collisionAlgorithmPool->~btPoolAllocator();
138 		btAlignedFree(m_collisionAlgorithmPool);
139 	}
140 	if (m_ownsPersistentManifoldPool)
141 	{
142 		m_persistentManifoldPool->~btPoolAllocator();
143 		btAlignedFree(m_persistentManifoldPool);
144 	}
145 
146 	m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
147 	btAlignedFree(m_convexConvexCreateFunc);
148 
149 	m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
150 	btAlignedFree(m_convexConcaveCreateFunc);
151 	m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
152 	btAlignedFree(m_swappedConvexConcaveCreateFunc);
153 
154 	m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
155 	btAlignedFree(m_compoundCreateFunc);
156 
157 	m_compoundCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
158 	btAlignedFree(m_compoundCompoundCreateFunc);
159 
160 	m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
161 	btAlignedFree(m_swappedCompoundCreateFunc);
162 
163 	m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
164 	btAlignedFree(m_emptyCreateFunc);
165 
166 	m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
167 	btAlignedFree(m_sphereSphereCF);
168 
169 #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
170 	m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
171 	btAlignedFree(m_sphereBoxCF);
172 	m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
173 	btAlignedFree(m_boxSphereCF);
174 #endif  //USE_BUGGY_SPHERE_BOX_ALGORITHM
175 
176 	m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
177 	btAlignedFree(m_sphereTriangleCF);
178 	m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
179 	btAlignedFree(m_triangleSphereCF);
180 	m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
181 	btAlignedFree(m_boxBoxCF);
182 
183 	m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
184 	btAlignedFree(m_convexPlaneCF);
185 	m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
186 	btAlignedFree(m_planeConvexCF);
187 
188 	m_pdSolver->~btConvexPenetrationDepthSolver();
189 
190 	btAlignedFree(m_pdSolver);
191 }
192 
getClosestPointsAlgorithmCreateFunc(int proxyType0,int proxyType1)193 btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1)
194 {
195 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
196 	{
197 		return m_sphereSphereCF;
198 	}
199 #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
200 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
201 	{
202 		return m_sphereBoxCF;
203 	}
204 
205 	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
206 	{
207 		return m_boxSphereCF;
208 	}
209 #endif  //USE_BUGGY_SPHERE_BOX_ALGORITHM
210 
211 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE))
212 	{
213 		return m_sphereTriangleCF;
214 	}
215 
216 	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
217 	{
218 		return m_triangleSphereCF;
219 	}
220 
221 	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
222 	{
223 		return m_convexPlaneCF;
224 	}
225 
226 	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
227 	{
228 		return m_planeConvexCF;
229 	}
230 
231 	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
232 	{
233 		return m_convexConvexCreateFunc;
234 	}
235 
236 	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
237 	{
238 		return m_convexConcaveCreateFunc;
239 	}
240 
241 	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
242 	{
243 		return m_swappedConvexConcaveCreateFunc;
244 	}
245 
246 	if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1))
247 	{
248 		return m_compoundCompoundCreateFunc;
249 	}
250 
251 	if (btBroadphaseProxy::isCompound(proxyType0))
252 	{
253 		return m_compoundCreateFunc;
254 	}
255 	else
256 	{
257 		if (btBroadphaseProxy::isCompound(proxyType1))
258 		{
259 			return m_swappedCompoundCreateFunc;
260 		}
261 	}
262 
263 	//failed to find an algorithm
264 	return m_emptyCreateFunc;
265 }
266 
getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)267 btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1)
268 {
269 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
270 	{
271 		return m_sphereSphereCF;
272 	}
273 #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
274 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
275 	{
276 		return m_sphereBoxCF;
277 	}
278 
279 	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
280 	{
281 		return m_boxSphereCF;
282 	}
283 #endif  //USE_BUGGY_SPHERE_BOX_ALGORITHM
284 
285 	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE))
286 	{
287 		return m_sphereTriangleCF;
288 	}
289 
290 	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
291 	{
292 		return m_triangleSphereCF;
293 	}
294 
295 	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
296 	{
297 		return m_boxBoxCF;
298 	}
299 
300 	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
301 	{
302 		return m_convexPlaneCF;
303 	}
304 
305 	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
306 	{
307 		return m_planeConvexCF;
308 	}
309 
310 	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
311 	{
312 		return m_convexConvexCreateFunc;
313 	}
314 
315 	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
316 	{
317 		return m_convexConcaveCreateFunc;
318 	}
319 
320 	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
321 	{
322 		return m_swappedConvexConcaveCreateFunc;
323 	}
324 
325 	if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1))
326 	{
327 		return m_compoundCompoundCreateFunc;
328 	}
329 
330 	if (btBroadphaseProxy::isCompound(proxyType0))
331 	{
332 		return m_compoundCreateFunc;
333 	}
334 	else
335 	{
336 		if (btBroadphaseProxy::isCompound(proxyType1))
337 		{
338 			return m_swappedCompoundCreateFunc;
339 		}
340 	}
341 
342 	//failed to find an algorithm
343 	return m_emptyCreateFunc;
344 }
345 
setConvexConvexMultipointIterations(int numPerturbationIterations,int minimumPointsPerturbationThreshold)346 void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
347 {
348 	btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*)m_convexConvexCreateFunc;
349 	convexConvex->m_numPerturbationIterations = numPerturbationIterations;
350 	convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
351 }
352 
setPlaneConvexMultipointIterations(int numPerturbationIterations,int minimumPointsPerturbationThreshold)353 void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
354 {
355 	btConvexPlaneCollisionAlgorithm::CreateFunc* cpCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_convexPlaneCF;
356 	cpCF->m_numPerturbationIterations = numPerturbationIterations;
357 	cpCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
358 
359 	btConvexPlaneCollisionAlgorithm::CreateFunc* pcCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_planeConvexCF;
360 	pcCF->m_numPerturbationIterations = numPerturbationIterations;
361 	pcCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
362 }
363