Bullet Collision Detection & Physics Library
btConvexConcaveCollisionAlgorithm.cpp
Go to the documentation of this file.
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 
29 
31 : btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
32 m_isSwapped(isSwapped),
33 m_btConvexTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped)
34 {
35 }
36 
38 {
39 }
40 
42 {
44  {
46  }
47 }
48 
49 
51  m_dispatcher(dispatcher),
52  m_dispatchInfoPtr(0)
53 {
54  m_convexBodyWrap = isSwapped? body1Wrap:body0Wrap;
55  m_triBodyWrap = isSwapped? body0Wrap:body1Wrap;
56 
57  //
58  // create the manifold from the dispatcher 'manifold pool'
59  //
61 
62  clearCache();
63 }
64 
66 {
67  clearCache();
69 
70 }
71 
72 
74 {
76 }
77 
78 
80 partId, int triangleIndex)
81 {
82 
84  {
85  return;
86  }
87 
88  //just for debugging purposes
89  //printf("triangle %d",m_triangleCount++);
90 
92 
95 
96  //const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
97 
98 
99 
100 
101 #if 0
104  {
105  btVector3 color(1,1,0);
106  btTransform& tr = ob->getWorldTransform();
107  m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
108  m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
109  m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
110  }
111 #endif
112 
114  {
115  btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
117 
118 
119  btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform(),partId,triangleIndex);//correct transform?
121 
122  const btCollisionObjectWrapper* tmpWrap = 0;
123 
125  {
126  tmpWrap = m_resultOut->getBody0Wrap();
127  m_resultOut->setBody0Wrap(&triObWrap);
128  m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
129  }
130  else
131  {
132  tmpWrap = m_resultOut->getBody1Wrap();
133  m_resultOut->setBody1Wrap(&triObWrap);
134  m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
135  }
136 
137  colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut);
138 
140  {
141  m_resultOut->setBody0Wrap(tmpWrap);
142  } else
143  {
144  m_resultOut->setBody1Wrap(tmpWrap);
145  }
146 
147 
148 
149  colAlgo->~btCollisionAlgorithm();
151  }
152 
153 }
154 
155 
156 
157 void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut)
158 {
159  m_convexBodyWrap = convexBodyWrap;
160  m_triBodyWrap = triBodyWrap;
161 
162  m_dispatchInfoPtr = &dispatchInfo;
163  m_collisionMarginTriangle = collisionMarginTriangle;
164  m_resultOut = resultOut;
165 
166  //recalc aabbs
167  btTransform convexInTriangleSpace;
169  const btCollisionShape* convexShape = static_cast<const btCollisionShape*>(m_convexBodyWrap->getCollisionShape());
170  //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
171  convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
172  btScalar extraMargin = collisionMarginTriangle;
173  btVector3 extra(extraMargin,extraMargin,extraMargin);
174 
175  m_aabbMax += extra;
176  m_aabbMin -= extra;
177 
178 }
179 
181 {
183 
184 }
185 
187 {
188 
189 
190  const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap;
191  const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap;
192 
193  if (triBodyWrap->getCollisionShape()->isConcave())
194  {
195 
196 
197 
198  const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>( triBodyWrap->getCollisionShape());
199 
200  if (convexBodyWrap->getCollisionShape()->isConvex())
201  {
202  btScalar collisionMarginTriangle = concaveShape->getMargin();
203 
205  m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,convexBodyWrap,triBodyWrap,resultOut);
206 
208 
210 
211  resultOut->refreshContactPoints();
212 
214 
215  }
216 
217  }
218 
219 }
220 
221 
223 {
224  (void)resultOut;
225  (void)dispatchInfo;
226  btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
227  btCollisionObject* triBody = m_isSwapped ? body0 : body1;
228 
229 
230  //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
231 
232  //only perform CCD above a certain threshold, this prevents blocking on the long run
233  //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
234  btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
235  if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
236  {
237  return btScalar(1.);
238  }
239 
240  //const btVector3& from = convexbody->m_worldTransform.getOrigin();
241  //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
242  //todo: only do if the motion exceeds the 'radius'
243 
244  btTransform triInv = triBody->getWorldTransform().inverse();
245  btTransform convexFromLocal = triInv * convexbody->getWorldTransform();
246  btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform();
247 
248  struct LocalTriangleSphereCastCallback : public btTriangleCallback
249  {
250  btTransform m_ccdSphereFromTrans;
251  btTransform m_ccdSphereToTrans;
252  btTransform m_meshTransform;
253 
254  btScalar m_ccdSphereRadius;
255  btScalar m_hitFraction;
256 
257 
258  LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
259  :m_ccdSphereFromTrans(from),
260  m_ccdSphereToTrans(to),
261  m_ccdSphereRadius(ccdSphereRadius),
262  m_hitFraction(hitFraction)
263  {
264  }
265 
266 
267  virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
268  {
269  (void)partId;
270  (void)triangleIndex;
271  //do a swept sphere for now
272  btTransform ident;
273  ident.setIdentity();
274  btConvexCast::CastResult castResult;
275  castResult.m_fraction = m_hitFraction;
276  btSphereShape pointShape(m_ccdSphereRadius);
277  btTriangleShape triShape(triangle[0],triangle[1],triangle[2]);
278  btVoronoiSimplexSolver simplexSolver;
279  btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver);
280  //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
281  //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
282  //local space?
283 
284  if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans,
285  ident,ident,castResult))
286  {
287  if (m_hitFraction > castResult.m_fraction)
288  m_hitFraction = castResult.m_fraction;
289  }
290 
291  }
292 
293  };
294 
295 
296 
297 
298 
299  if (triBody->getCollisionShape()->isConcave())
300  {
301  btVector3 rayAabbMin = convexFromLocal.getOrigin();
302  rayAabbMin.setMin(convexToLocal.getOrigin());
303  btVector3 rayAabbMax = convexFromLocal.getOrigin();
304  rayAabbMax.setMax(convexToLocal.getOrigin());
305  btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
306  rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
307  rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
308 
309  btScalar curHitFraction = btScalar(1.); //is this available?
310  LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
311  convexbody->getCcdSweptSphereRadius(),curHitFraction);
312 
313  raycastCallback.m_hitFraction = convexbody->getHitFraction();
314 
315  btCollisionObject* concavebody = triBody;
316 
317  btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape();
318 
319  if (triangleMesh)
320  {
321  triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
322  }
323 
324 
325 
326  if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
327  {
328  convexbody->setHitFraction( raycastCallback.m_hitFraction);
329  return raycastCallback.m_hitFraction;
330  }
331  }
332 
333  return btScalar(1.);
334 
335 }
virtual void releaseManifold(btPersistentManifold *manifold)=0
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
void push_back(const T &_Val)
const btDispatcherInfo * m_dispatchInfoPtr
btScalar getCcdSweptSphereRadius() const
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
virtual btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold=0)=0
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
void setPersistentManifold(btPersistentManifold *manifoldPtr)
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
This class is not enabled yet (work-in-progress) to more aggressively activate objects.
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
void setHitFraction(btScalar hitFraction)
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
btManifoldResult is a helper class to manage contact results.
class btIDebugDraw * m_debugDraw
Definition: btDispatcher.h:58
const btCollisionObjectWrapper * getBody1Wrap() const
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const =0
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...
const btTransform & getInterpolationWorldTransform() const
virtual void setShapeIdentifiersA(int partId0, int index0)
setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material comb...
bool isConcave() const
btTransform & getWorldTransform()
virtual void setMargin(btScalar margin)
RayResult stores the closest result alternatively, add a callback method to decide about closest/all ...
Definition: btConvexCast.h:36
const btCollisionObjectWrapper * m_convexBodyWrap
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
const btCollisionObjectWrapper * getBody0Wrap() const
btScalar calculateTimeOfImpact(btCollisionObject *body0, btCollisionObject *body1, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)
virtual bool calcTimeOfImpact(const btTransform &fromA, const btTransform &toA, const btTransform &fromB, const btTransform &toB, CastResult &result)
SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (...
const btTransform & getWorldTransform() const
btCollisionObject can be used to manage collision detection objects.
void setTimeStepAndCounters(btScalar collisionMarginTriangle, const btDispatcherInfo &dispatchInfo, const btCollisionObjectWrapper *convexBodyWrap, const btCollisionObjectWrapper *triBodyWrap, btManifoldResult *resultOut)
const btCollisionObject * getBody0Internal() const
virtual void freeCollisionAlgorithm(void *ptr)=0
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
btTransform inverse() const
Return the inverse of this transform.
Definition: btTransform.h:188
virtual void setShapeIdentifiersB(int partId1, int index1)
const btCollisionShape * getCollisionShape() const
btScalar getHitFraction() const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btSubsimplexConvexCast implements Gino van den Bergens' paper "Ray Casting against bteral Convex Obje...
bool isConvex() const
The btConcaveShape class provides an interface for non-moving (static) concave shapes.
virtual int getDebugMode() const =0
void setBody1Wrap(const btCollisionObjectWrapper *obj1Wrap)
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)
const btCollisionObjectWrapper * m_triBodyWrap
btConvexConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped)
btConvexTriangleCallback(btDispatcher *dispatcher, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped)
virtual btScalar getMargin() const
void setBody0Wrap(const btCollisionObjectWrapper *obj0Wrap)
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
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
const btCollisionShape * getCollisionShape() const
bool TestTriangleAgainstAabb2(const btVector3 *vertices, const btVector3 &aabbMin, const btVector3 &aabbMax)
conservative test for overlap between triangle and aabb
Definition: btAabbUtil2.h:59
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
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
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
const btCollisionObject * getCollisionObject() const
virtual void clearManifold(btPersistentManifold *manifold)=0