Blender V4.3
btCollisionDispatcher.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
18
20
27
28#ifdef BT_DEBUG
29#include <stdio.h>
30#endif
31
32btCollisionDispatcher::btCollisionDispatcher(btCollisionConfiguration* collisionConfiguration) : m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
33 m_collisionConfiguration(collisionConfiguration)
34{
35 int i;
36
38
40
42
43 for (i = 0; i < MAX_BROADPHASE_COLLISION_TYPES; i++)
44 {
45 for (int j = 0; j < MAX_BROADPHASE_COLLISION_TYPES; j++)
46 {
50 }
51 }
52}
53
55{
56 m_doubleDispatchContactPoints[proxyType0][proxyType1] = createFunc;
57}
58
60{
61 m_doubleDispatchClosestPoints[proxyType0][proxyType1] = createFunc;
62}
63
67
68btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0, const btCollisionObject* body1)
69{
70 //btAssert(gNumManifold < 65535);
71
72 //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
73
74 btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold), body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold))
76
77 btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(), body1->getContactProcessingThreshold());
78
80 if (NULL == mem)
81 {
82 //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
84 {
85 mem = btAlignedAlloc(sizeof(btPersistentManifold), 16);
86 }
87 else
88 {
89 btAssert(0);
90 //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration
91 return 0;
92 }
93 }
94 btPersistentManifold* manifold = new (mem) btPersistentManifold(body0, body1, 0, contactBreakingThreshold, contactProcessingThreshold);
95 manifold->m_index1a = m_manifoldsPtr.size();
96 m_manifoldsPtr.push_back(manifold);
97
98 return manifold;
99}
100
102{
103 manifold->clearManifold();
104}
105
107{
108 //printf("releaseManifold: gNumManifold %d\n",gNumManifold);
109 clearManifold(manifold);
110
111 int findIndex = manifold->m_index1a;
112 btAssert(findIndex < m_manifoldsPtr.size());
113 m_manifoldsPtr.swap(findIndex, m_manifoldsPtr.size() - 1);
114 m_manifoldsPtr[findIndex]->m_index1a = findIndex;
116
117 manifold->~btPersistentManifold();
119 {
121 }
122 else
123 {
124 btAlignedFree(manifold);
125 }
126}
127
129{
131
132 ci.m_dispatcher1 = this;
133 ci.m_manifold = sharedManifold;
134 btCollisionAlgorithm* algo = 0;
135 if (algoType == BT_CONTACT_POINT_ALGORITHMS)
136 {
137 algo = m_doubleDispatchContactPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
138 }
139 else
140 {
141 algo = m_doubleDispatchClosestPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
142 }
143
144 return algo;
145}
146
147bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0, const btCollisionObject* body1)
148{
149 //here you can do filtering
150 bool hasResponse =
151 (body0->hasContactResponse() && body1->hasContactResponse());
152 //no response between two static/kinematic bodies:
153 hasResponse = hasResponse &&
154 ((!body0->isStaticOrKinematicObject()) || (!body1->isStaticOrKinematicObject()));
155 return hasResponse;
156}
157
158bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0, const btCollisionObject* body1)
159{
160 btAssert(body0);
161 btAssert(body1);
162
163 bool needsCollision = true;
164
165#ifdef BT_DEBUG
167 {
168 //broadphase filtering already deals with this
169 if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject())
170 {
172 printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
173 }
174 }
175#endif //BT_DEBUG
176
177 if ((!body0->isActive()) && (!body1->isActive()))
178 needsCollision = false;
179 else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
180 needsCollision = false;
181
182 return needsCollision;
183}
184
188{
189 const btDispatcherInfo& m_dispatchInfo;
190 btCollisionDispatcher* m_dispatcher;
191
192public:
194 : m_dispatchInfo(dispatchInfo),
195 m_dispatcher(dispatcher)
196 {
197 }
198
199 /*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
200 {
201 m_dispatchInfo = other.m_dispatchInfo;
202 m_dispatcher = other.m_dispatcher;
203 return *this;
204 }
205 */
206
208
210 {
211 (*m_dispatcher->getNearCallback())(pair, *m_dispatcher, m_dispatchInfo);
212 return false;
213 }
214};
215
217{
218 //m_blockedForChanges = true;
219
220 btCollisionPairCallback collisionCallback(dispatchInfo, this);
221
222 {
223 BT_PROFILE("processAllOverlappingPairs");
224 pairCache->processAllOverlappingPairs(&collisionCallback, dispatcher, dispatchInfo);
225 }
226
227 //m_blockedForChanges = false;
228}
229
230//by default, Bullet will use this near callback
232{
233 btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
234 btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
235
236 if (dispatcher.needsCollision(colObj0, colObj1))
237 {
238 btCollisionObjectWrapper obj0Wrap(0, colObj0->getCollisionShape(), colObj0, colObj0->getWorldTransform(), -1, -1);
239 btCollisionObjectWrapper obj1Wrap(0, colObj1->getCollisionShape(), colObj1, colObj1->getWorldTransform(), -1, -1);
240
241 //dispatcher will keep algorithms persistent in the collision pair
242 if (!collisionPair.m_algorithm)
243 {
244 collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap, &obj1Wrap, 0, BT_CONTACT_POINT_ALGORITHMS);
245 }
246
247 if (collisionPair.m_algorithm)
248 {
249 btManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap);
250
252 {
253 //discrete collision detection query
254
255 collisionPair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatchInfo, &contactPointResult);
256 }
257 else
258 {
259 //continuous collision detection query, time of impact (toi)
260 btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0, colObj1, dispatchInfo, &contactPointResult);
261 if (dispatchInfo.m_timeOfImpact > toi)
262 dispatchInfo.m_timeOfImpact = toi;
263 }
264 }
265 }
266}
267
269{
271 if (NULL == mem)
272 {
273 //warn user for overflow?
274 return btAlignedAlloc(static_cast<size_t>(size), 16);
275 }
276 return mem;
277}
278
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
@ MAX_BROADPHASE_COLLISION_TYPES
btBroadphasePair
btScalar gContactBreakingThreshold
btDispatcher * m_dispatcher
ebtDispatcherQueryType
@ BT_CONTACT_POINT_ALGORITHMS
SIMD_FORCE_INLINE const T & btMin(const T &a, const T &b)
Definition btMinMax.h:21
SIMD_FORCE_INLINE void clearManifold()
btPersistentManifold()
#define BT_PROFILE(name)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define btAssert(x)
Definition btScalar.h:295
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
void swap(int index0, int index1)
SIMD_FORCE_INLINE void pop_back()
SIMD_FORCE_INLINE void push_back(const T &_Val)
virtual btPoolAllocator * getPersistentManifoldPool()=0
memory pools
virtual btCollisionAlgorithmCreateFunc * getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1)=0
virtual btPoolAllocator * getCollisionAlgorithmPool()=0
virtual btCollisionAlgorithmCreateFunc * getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1)=0
btCollisionAlgorithmCreateFunc * m_doubleDispatchClosestPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]
virtual void releaseManifold(btPersistentManifold *manifold)
void registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
btCollisionConfiguration * m_collisionConfiguration
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)
btCollisionDispatcher(btCollisionConfiguration *collisionConfiguration)
void setNearCallback(btNearCallback nearCallback)
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)
virtual void freeCollisionAlgorithm(void *ptr)
btCollisionAlgorithmCreateFunc * m_doubleDispatchContactPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]
static void defaultNearCallback(btBroadphasePair &collisionPair, btCollisionDispatcher &dispatcher, const btDispatcherInfo &dispatchInfo)
virtual void dispatchAllCollisionPairs(btOverlappingPairCache *pairCache, const btDispatcherInfo &dispatchInfo, btDispatcher *dispatcher)
btPoolAllocator * m_collisionAlgorithmPoolAllocator
virtual void clearManifold(btPersistentManifold *manifold)
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)
btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)
virtual void * allocateCollisionAlgorithm(int size)
btAlignedObjectArray< btPersistentManifold * > m_manifoldsPtr
btPoolAllocator * m_persistentManifoldPoolAllocator
void registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
registerCollisionCreateFunc allows registration of custom/alternative collision create functions
virtual bool processOverlap(btBroadphasePair &pair)
btCollisionPairCallback(const btDispatcherInfo &dispatchInfo, btCollisionDispatcher *dispatcher)
btManifoldResult is a helper class to manage contact results.
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
void freeMemory(void *ptr)
bool validPtr(void *ptr)
void * allocate(int size)
#define printf
#define NULL
Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm.
virtual btCollisionAlgorithm * CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo &, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap)
SIMD_FORCE_INLINE const btCollisionShape * getCollisionShape() const
btScalar m_timeOfImpact
PointerRNA * ptr
Definition wm_files.cc:4126