Bullet Collision Detection & Physics Library
btConvexConcaveCollisionAlgorithm.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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
30
32 : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap),
33 m_btConvexTriangleCallback(ci.m_dispatcher1, body0Wrap, body1Wrap, isSwapped),
34 m_isSwapped(isSwapped)
35{
36}
37
39{
40}
41
43{
45 {
47 }
48}
49
51 m_dispatchInfoPtr(0)
52{
53 m_convexBodyWrap = isSwapped ? body1Wrap : body0Wrap;
54 m_triBodyWrap = isSwapped ? body0Wrap : body1Wrap;
55
56 //
57 // create the manifold from the dispatcher 'manifold pool'
58 //
60
61 clearCache();
62}
63
65{
66 clearCache();
68}
69
71{
73}
74
76{
77 BT_PROFILE("btConvexTriangleCallback::processTriangle");
78
80 {
81 return;
82 }
83
84 //just for debugging purposes
85 //printf("triangle %d",m_triangleCount++);
86
89
90#if 0
91
94 {
96 btVector3 color(1,1,0);
97 btTransform& tr = ob->getWorldTransform();
101 }
102#endif
103
105 {
106#ifdef BT_ENABLE_CONVEX_CONCAVE_EARLY_OUT
107 //todo: check this issue https://github.com/bulletphysics/bullet3/issues/4263
108 //an early out optimisation if the object is separated from the triangle
109 //projected on the triangle normal)
110 {
114
115 btVector3 triangle_normal_world = ( v1 - v0).cross(v2 - v0);
117
119
122 //now check if this is fully on one side of the triangle
127 if (dist > contact_threshold)
128 return;
129
130 //also check the other side of the triangle
132
135 //now check if this is fully on one side of the triangle
138
139 dist = proj_distTr - proj_distPt;
140 if (dist > contact_threshold)
141 return;
142 }
143#endif //BT_ENABLE_CONVEX_CONCAVE_EARLY_OUT
144
146 tm.setMargin(m_collisionMarginTriangle);
147
150
152 {
153 colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap, &triObWrap, 0, BT_CLOSEST_POINT_ALGORITHMS);
154 }
155 else
156 {
158 }
160
162 {
166 }
167 else
168 {
172 }
173
174 {
175 BT_PROFILE("processCollision (GJK?)");
177 }
178
180 {
182 }
183 else
184 {
186 }
187
188 colAlgo->~btCollisionAlgorithm();
189 ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
190 }
191}
192
194{
197
201
202 //recalc aabbs
206 //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
208 btScalar extraMargin = collisionMarginTriangle + resultOut->m_closestPointDistanceThreshold;
209
211
212 m_aabbMax += extra;
213 m_aabbMin -= extra;
214}
215
217{
219}
220
222{
223 BT_PROFILE("btConvexConcaveCollisionAlgorithm::processCollision");
224
225 const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap;
226 const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap;
227
228 if (triBodyWrap->getCollisionShape()->isConcave())
229 {
230 if (triBodyWrap->getCollisionShape()->getShapeType() == SDF_SHAPE_PROXYTYPE)
231 {
233 if (convexBodyWrap->getCollisionShape()->isConvex())
234 {
235 btConvexShape* convex = (btConvexShape*)convexBodyWrap->getCollisionShape();
237
238 if (convex->isPolyhedral())
239 {
241 for (int v = 0; v < poly->getNumVertices(); v++)
242 {
244 poly->getVertex(v, vtx);
245 queryVertices.push_back(vtx);
246 }
247 }
249
250 if (convex->getShapeType() == SPHERE_SHAPE_PROXYTYPE)
251 {
252 queryVertices.push_back(btVector3(0, 0, 0));
255 }
256 if (queryVertices.size())
257 {
258 resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
259 //m_btConvexTriangleCallback.m_manifoldPtr->clearManifold();
260
262 for (int v = 0; v < queryVertices.size(); v++)
263 {
264 const btVector3& vtx = queryVertices[v];
265 btVector3 vtxWorldSpace = convexBodyWrap->getWorldTransform() * vtx;
266 btVector3 vtxInSdf = triBodyWrap->getWorldTransform().invXform(vtxWorldSpace);
267
269 btScalar dist;
270 if (sdfShape->queryPoint(vtxInSdf, dist, normalLocal))
271 {
272 if (dist <= maxDist)
273 {
275 btVector3 normal = triBodyWrap->getWorldTransform().getBasis() * normalLocal;
276
277 if (convex->getShapeType() == SPHERE_SHAPE_PROXYTYPE)
278 {
280 dist -= sphere->getRadius();
281 vtxWorldSpace -= sphere->getRadius() * normal;
282 }
283 resultOut->addContactPoint(normal, vtxWorldSpace - normal * dist, dist);
284 }
285 }
286 }
287 resultOut->refreshContactPoints();
288 }
289 }
290 }
291 else
292 {
293 const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>(triBodyWrap->getCollisionShape());
294
295 if (convexBodyWrap->getCollisionShape()->isConvex())
296 {
298
299 resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
301
302 m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(), triBodyWrap->getCollisionObject());
303
305
306 resultOut->refreshContactPoints();
307
309 }
310 }
311 }
312}
313
315{
320
321 //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
322
323 //only perform CCD above a certain threshold, this prevents blocking on the long run
324 //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
325 btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
326 if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
327 {
328 return btScalar(1.);
329 }
330
331 //const btVector3& from = convexbody->m_worldTransform.getOrigin();
332 //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
333 //todo: only do if the motion exceeds the 'radius'
334
335 btTransform triInv = triBody->getWorldTransform().inverse();
336 btTransform convexFromLocal = triInv * convexbody->getWorldTransform();
337 btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform();
338
340 {
344
346 btScalar m_hitFraction;
347
352 m_hitFraction(hitFraction)
353 {
354 }
355
356 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
357 {
358 BT_PROFILE("processTriangle");
359 (void)partId;
361 //do a swept sphere for now
365 castResult.m_fraction = m_hitFraction;
370 //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
371 //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
372 //local space?
373
376 {
377 if (m_hitFraction > castResult.m_fraction)
378 m_hitFraction = castResult.m_fraction;
379 }
380 }
381 };
382
383 if (triBody->getCollisionShape()->isConcave())
384 {
386 rayAabbMin.setMin(convexToLocal.getOrigin());
388 rayAabbMax.setMax(convexToLocal.getOrigin());
389 btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
392
393 btScalar curHitFraction = btScalar(1.); //is this available?
395 convexbody->getCcdSweptSphereRadius(), curHitFraction);
396
397 raycastCallback.m_hitFraction = convexbody->getHitFraction();
398
400
401 btConcaveShape* triangleMesh = (btConcaveShape*)concavebody->getCollisionShape();
402
403 if (triangleMesh)
404 {
406 }
407
408 if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
409 {
410 convexbody->setHitFraction(raycastCallback.m_hitFraction);
411 return raycastCallback.m_hitFraction;
412 }
413 }
414
415 return btScalar(1.);
416}
bool TestTriangleAgainstAabb2(const btVector3 *vertices, const btVector3 &aabbMin, const btVector3 &aabbMax)
conservative test for overlap between triangle and aabb
Definition btAabbUtil2.h:54
@ SDF_SHAPE_PROXYTYPE
@ SPHERE_SHAPE_PROXYTYPE
@ BT_CLOSEST_POINT_ALGORITHMS
@ BT_CONTACT_POINT_ALGORITHMS
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
#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 SIMD_EPSILON
Definition btScalar.h:543
This class is not enabled yet (work-in-progress) to more aggressively activate objects.
void push_back(const T &_Val)
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
btCollisionObject can be used to manage collision detection objects.
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
bool isConvex() const
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
The btConcaveShape class provides an interface for non-moving (static) concave shapes.
virtual btScalar getMargin() const
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const =0
btConvexConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped)
btScalar calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
btConvexTriangleCallback(btDispatcher *dispatcher, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped)
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
void setTimeStepAndCounters(btScalar collisionMarginTriangle, const btDispatcherInfo &dispatchInfo, const btCollisionObjectWrapper *convexBodyWrap, const btCollisionObjectWrapper *triBodyWrap, btManifoldResult *resultOut)
const btCollisionObjectWrapper * m_convexBodyWrap
const btCollisionObjectWrapper * m_triBodyWrap
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
virtual void clearManifold(btPersistentManifold *manifold)=0
virtual void releaseManifold(btPersistentManifold *manifold)=0
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual int getDebugMode() const =0
btManifoldResult is a helper class to manage contact results.
virtual void setShapeIdentifiersA(int partId0, int index0)
setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material comb...
void setBody0Wrap(const btCollisionObjectWrapper *obj0Wrap)
const btCollisionObjectWrapper * getBody1Wrap() const
void setBody1Wrap(const btCollisionObjectWrapper *obj1Wrap)
const btCollisionObject * getBody0Internal() const
virtual void setShapeIdentifiersB(int partId1, int index1)
btScalar m_closestPointDistanceThreshold
const btCollisionObjectWrapper * getBody0Wrap() const
btMatrix3x3 inverse() const
Return the inverse of the matrix.
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
btScalar getContactBreakingThreshold() const
The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
The btSphereShape implements an implicit sphere, centered around a local origin with radius.
btScalar getRadius() const
btSubsimplexConvexCast implements Gino van den Bergens' paper "Ray Casting against bteral Convex Obje...
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
btTransform inverse() const
Return the inverse of this transform.
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
void setIdentity()
Set this transformation to the identity.
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition btVector3.h:609
btVector3 & safeNormalize()
Definition btVector3.h:286
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition btVector3.h:626
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
const btCollisionShape * getCollisionShape() const
const btCollisionObject * getCollisionObject() const
const btTransform & getWorldTransform() const
RayResult stores the closest result alternatively, add a callback method to decide about closest/all ...
class btIDebugDraw * m_debugDraw