Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @ 8043

Last change on this file since 8043 was 7983, checked in by rgrieder, 14 years ago

Updated Bullet Physics Engine from v2.74 to v2.77

  • Property svn:eol-style set to native
File size: 10.9 KB
Line 
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
16
17#include "btConvexConcaveCollisionAlgorithm.h"
18#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
19#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
20#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
21#include "BulletCollision/CollisionShapes/btConcaveShape.h"
22#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
23#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
24#include "BulletCollision/CollisionShapes/btTriangleShape.h"
25#include "BulletCollision/CollisionShapes/btSphereShape.h"
26#include "LinearMath/btIDebugDraw.h"
27#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
28
29btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
30: btActivatingCollisionAlgorithm(ci,body0,body1),
31m_isSwapped(isSwapped),
32m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
33{
34}
35
36btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm()
37{
38}
39
40void    btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray&      manifoldArray)
41{
42        if (m_btConvexTriangleCallback.m_manifoldPtr)
43        {
44                manifoldArray.push_back(m_btConvexTriangleCallback.m_manifoldPtr);
45        }
46}
47
48
49btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher*  dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
50          m_dispatcher(dispatcher),
51        m_dispatchInfoPtr(0)
52{
53        m_convexBody = isSwapped? body1:body0;
54        m_triBody = isSwapped? body0:body1;
55       
56          //
57          // create the manifold from the dispatcher 'manifold pool'
58          //
59          m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
60
61          clearCache();
62}
63
64btConvexTriangleCallback::~btConvexTriangleCallback()
65{
66        clearCache();
67        m_dispatcher->releaseManifold( m_manifoldPtr );
68 
69}
70 
71
72void    btConvexTriangleCallback::clearCache()
73{
74        m_dispatcher->clearManifold(m_manifoldPtr);
75}
76
77
78
79void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
80{
81 
82        //just for debugging purposes
83        //printf("triangle %d",m_triangleCount++);
84
85
86        //aabb filter is already applied!       
87
88        btCollisionAlgorithmConstructionInfo ci;
89        ci.m_dispatcher1 = m_dispatcher;
90
91        btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
92
93
94       
95        ///debug drawing of the overlapping triangles
96        if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
97        {
98                btVector3 color(1,1,0);
99                btTransform& tr = ob->getWorldTransform();
100                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
101                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
102                m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
103
104                //btVector3 center = triangle[0] + triangle[1]+triangle[2];
105                //center *= btScalar(0.333333);
106                //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
107                //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
108                //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
109
110        }
111
112
113        //btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
114       
115        if (m_convexBody->getCollisionShape()->isConvex())
116        {
117                btTriangleShape tm(triangle[0],triangle[1],triangle[2]);       
118                tm.setMargin(m_collisionMarginTriangle);
119               
120                btCollisionShape* tmpShape = ob->getCollisionShape();
121                ob->internalSetTemporaryCollisionShape( &tm );
122               
123                btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
124
125                if (m_resultOut->getBody0Internal() == m_triBody)
126                {
127                        m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
128                }
129                else
130                {
131                        m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
132                }
133       
134                colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
135                colAlgo->~btCollisionAlgorithm();
136                ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
137                ob->internalSetTemporaryCollisionShape( tmpShape);
138        }
139
140
141}
142
143
144
145void    btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
146{
147        m_dispatchInfoPtr = &dispatchInfo;
148        m_collisionMarginTriangle = collisionMarginTriangle;
149        m_resultOut = resultOut;
150
151        //recalc aabbs
152        btTransform convexInTriangleSpace;
153        convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform();
154        btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
155        //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
156        convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
157        btScalar extraMargin = collisionMarginTriangle;
158        btVector3 extra(extraMargin,extraMargin,extraMargin);
159
160        m_aabbMax += extra;
161        m_aabbMin -= extra;
162       
163}
164
165void btConvexConcaveCollisionAlgorithm::clearCache()
166{
167        m_btConvexTriangleCallback.clearCache();
168
169}
170
171void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
172{
173       
174       
175        btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
176        btCollisionObject* triBody = m_isSwapped ? body0 : body1;
177
178        if (triBody->getCollisionShape()->isConcave())
179        {
180
181
182                btCollisionObject*      triOb = triBody;
183                btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
184               
185                if (convexBody->getCollisionShape()->isConvex())
186                {
187                        btScalar collisionMarginTriangle = concaveShape->getMargin();
188                                       
189                        resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
190                        m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
191
192                        //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
193                        //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
194
195                        m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
196
197                        concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
198                       
199                        resultOut->refreshContactPoints();
200       
201                }
202       
203        }
204
205}
206
207
208btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
209{
210        (void)resultOut;
211        (void)dispatchInfo;
212        btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
213        btCollisionObject* triBody = m_isSwapped ? body0 : body1;
214
215
216        //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
217
218        //only perform CCD above a certain threshold, this prevents blocking on the long run
219        //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
220        btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
221        if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
222        {
223                return btScalar(1.);
224        }
225
226        //const btVector3& from = convexbody->m_worldTransform.getOrigin();
227        //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
228        //todo: only do if the motion exceeds the 'radius'
229
230        btTransform triInv = triBody->getWorldTransform().inverse();
231        btTransform convexFromLocal = triInv * convexbody->getWorldTransform();
232        btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform();
233
234        struct LocalTriangleSphereCastCallback  : public btTriangleCallback
235        {
236                btTransform m_ccdSphereFromTrans;
237                btTransform m_ccdSphereToTrans;
238                btTransform     m_meshTransform;
239
240                btScalar        m_ccdSphereRadius;
241                btScalar        m_hitFraction;
242       
243
244                LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
245                        :m_ccdSphereFromTrans(from),
246                        m_ccdSphereToTrans(to),
247                        m_ccdSphereRadius(ccdSphereRadius),
248                        m_hitFraction(hitFraction)
249                {                       
250                }
251               
252               
253                virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
254                {
255                        (void)partId;
256                        (void)triangleIndex;
257                        //do a swept sphere for now
258                        btTransform ident;
259                        ident.setIdentity();
260                        btConvexCast::CastResult castResult;
261                        castResult.m_fraction = m_hitFraction;
262                        btSphereShape   pointShape(m_ccdSphereRadius);
263                        btTriangleShape triShape(triangle[0],triangle[1],triangle[2]);
264                        btVoronoiSimplexSolver  simplexSolver;
265                        btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver);
266                        //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
267                        //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
268                        //local space?
269
270                        if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans,
271                                ident,ident,castResult))
272                        {
273                                if (m_hitFraction > castResult.m_fraction)
274                                        m_hitFraction = castResult.m_fraction;
275                        }
276
277                }
278
279        };
280
281
282       
283
284       
285        if (triBody->getCollisionShape()->isConcave())
286        {
287                btVector3 rayAabbMin = convexFromLocal.getOrigin();
288                rayAabbMin.setMin(convexToLocal.getOrigin());
289                btVector3 rayAabbMax = convexFromLocal.getOrigin();
290                rayAabbMax.setMax(convexToLocal.getOrigin());
291                btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
292                rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
293                rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
294
295                btScalar curHitFraction = btScalar(1.); //is this available?
296                LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
297                        convexbody->getCcdSweptSphereRadius(),curHitFraction);
298
299                raycastCallback.m_hitFraction = convexbody->getHitFraction();
300
301                btCollisionObject* concavebody = triBody;
302
303                btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape();
304               
305                if (triangleMesh)
306                {
307                        triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
308                }
309       
310
311
312                if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
313                {
314                        convexbody->setHitFraction( raycastCallback.m_hitFraction);
315                        return raycastCallback.m_hitFraction;
316                }
317        }
318
319        return btScalar(1.);
320
321}
Note: See TracBrowser for help on using the repository browser.