~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/bullet/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "btCollisionWorld.h"
 
17
#include "btCollisionDispatcher.h"
 
18
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
 
19
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
 
20
#include "BulletCollision/CollisionShapes/btConvexShape.h"
 
21
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
 
22
#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
 
23
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
 
24
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
 
25
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
 
26
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
 
27
#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
 
28
#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
 
29
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
 
30
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
 
31
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
 
32
#include "LinearMath/btAabbUtil2.h"
 
33
#include "LinearMath/btQuickprof.h"
 
34
#include "LinearMath/btStackAlloc.h"
 
35
#include "LinearMath/btSerializer.h"
 
36
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
 
37
 
 
38
//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
 
39
 
 
40
 
 
41
//#define USE_BRUTEFORCE_RAYBROADPHASE 1
 
42
//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation'  or 'updateAabbs' before using a rayTest
 
43
//#define RECALCULATE_AABB_RAYCAST 1
 
44
 
 
45
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
 
46
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
 
47
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
 
48
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
 
49
 
 
50
 
 
51
///for debug drawing
 
52
 
 
53
//for debug rendering
 
54
#include "BulletCollision/CollisionShapes/btBoxShape.h"
 
55
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
 
56
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
 
57
#include "BulletCollision/CollisionShapes/btConeShape.h"
 
58
#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
 
59
#include "BulletCollision/CollisionShapes/btCylinderShape.h"
 
60
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
 
61
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
 
62
#include "BulletCollision/CollisionShapes/btSphereShape.h"
 
63
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
 
64
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
 
65
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
 
66
 
 
67
 
 
68
 
 
69
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
 
70
:m_dispatcher1(dispatcher),
 
71
m_broadphasePairCache(pairCache),
 
72
m_debugDrawer(0),
 
73
m_forceUpdateAllAabbs(true)
 
74
{
 
75
        m_stackAlloc = collisionConfiguration->getStackAllocator();
 
76
        m_dispatchInfo.m_stackAllocator = m_stackAlloc;
 
77
}
 
78
 
 
79
 
 
80
btCollisionWorld::~btCollisionWorld()
 
81
{
 
82
 
 
83
        //clean up remaining objects
 
84
        int i;
 
85
        for (i=0;i<m_collisionObjects.size();i++)
 
86
        {
 
87
                btCollisionObject* collisionObject= m_collisionObjects[i];
 
88
 
 
89
                btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
 
90
                if (bp)
 
91
                {
 
92
                        //
 
93
                        // only clear the cached algorithms
 
94
                        //
 
95
                        getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
 
96
                        getBroadphase()->destroyProxy(bp,m_dispatcher1);
 
97
                        collisionObject->setBroadphaseHandle(0);
 
98
                }
 
99
        }
 
100
 
 
101
 
 
102
}
 
103
 
 
104
 
 
105
 
 
106
 
 
107
 
 
108
 
 
109
 
 
110
 
 
111
 
 
112
 
 
113
void    btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
 
114
{
 
115
 
 
116
        btAssert(collisionObject);
 
117
 
 
118
        //check that the object isn't already added
 
119
        btAssert( m_collisionObjects.findLinearSearch(collisionObject)  == m_collisionObjects.size());
 
120
 
 
121
        m_collisionObjects.push_back(collisionObject);
 
122
 
 
123
        //calculate new AABB
 
124
        btTransform trans = collisionObject->getWorldTransform();
 
125
 
 
126
        btVector3       minAabb;
 
127
        btVector3       maxAabb;
 
128
        collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
 
129
 
 
130
        int type = collisionObject->getCollisionShape()->getShapeType();
 
131
        collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
 
132
                minAabb,
 
133
                maxAabb,
 
134
                type,
 
135
                collisionObject,
 
136
                collisionFilterGroup,
 
137
                collisionFilterMask,
 
138
                m_dispatcher1,0
 
139
                ))      ;
 
140
 
 
141
 
 
142
 
 
143
 
 
144
 
 
145
}
 
146
 
 
147
 
 
148
 
 
149
void    btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
 
150
{
 
151
        btVector3 minAabb,maxAabb;
 
152
        colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
 
153
        //need to increase the aabb for contact thresholds
 
154
        btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
 
155
        minAabb -= contactThreshold;
 
156
        maxAabb += contactThreshold;
 
157
 
 
158
        if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
 
159
        {
 
160
                btVector3 minAabb2,maxAabb2;
 
161
                colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
 
162
                minAabb2 -= contactThreshold;
 
163
                maxAabb2 += contactThreshold;
 
164
                minAabb.setMin(minAabb2);
 
165
                maxAabb.setMax(maxAabb2);
 
166
        }
 
167
 
 
168
        btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
 
169
 
 
170
        //moving objects should be moderately sized, probably something wrong if not
 
171
        if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
 
172
        {
 
173
                bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
 
174
        } else
 
175
        {
 
176
                //something went wrong, investigate
 
177
                //this assert is unwanted in 3D modelers (danger of loosing work)
 
178
                colObj->setActivationState(DISABLE_SIMULATION);
 
179
 
 
180
                static bool reportMe = true;
 
181
                if (reportMe && m_debugDrawer)
 
182
                {
 
183
                        reportMe = false;
 
184
                        m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
 
185
                        m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
 
186
                        m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
 
187
                        m_debugDrawer->reportErrorWarning("Thanks.\n");
 
188
                }
 
189
        }
 
190
}
 
191
 
 
192
void    btCollisionWorld::updateAabbs()
 
193
{
 
194
        BT_PROFILE("updateAabbs");
 
195
 
 
196
        btTransform predictedTrans;
 
197
        for ( int i=0;i<m_collisionObjects.size();i++)
 
198
        {
 
199
                btCollisionObject* colObj = m_collisionObjects[i];
 
200
 
 
201
                //only update aabb of active objects
 
202
                if (m_forceUpdateAllAabbs || colObj->isActive())
 
203
                {
 
204
                        updateSingleAabb(colObj);
 
205
                }
 
206
        }
 
207
}
 
208
 
 
209
 
 
210
 
 
211
void    btCollisionWorld::performDiscreteCollisionDetection()
 
212
{
 
213
        BT_PROFILE("performDiscreteCollisionDetection");
 
214
 
 
215
        btDispatcherInfo& dispatchInfo = getDispatchInfo();
 
216
 
 
217
        updateAabbs();
 
218
 
 
219
        {
 
220
                BT_PROFILE("calculateOverlappingPairs");
 
221
                m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
 
222
        }
 
223
 
 
224
 
 
225
        btDispatcher* dispatcher = getDispatcher();
 
226
        {
 
227
                BT_PROFILE("dispatchAllCollisionPairs");
 
228
                if (dispatcher)
 
229
                        dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
 
230
        }
 
231
 
 
232
}
 
233
 
 
234
 
 
235
 
 
236
void    btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
 
237
{
 
238
 
 
239
 
 
240
        //bool removeFromBroadphase = false;
 
241
 
 
242
        {
 
243
 
 
244
                btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
 
245
                if (bp)
 
246
                {
 
247
                        //
 
248
                        // only clear the cached algorithms
 
249
                        //
 
250
                        getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
 
251
                        getBroadphase()->destroyProxy(bp,m_dispatcher1);
 
252
                        collisionObject->setBroadphaseHandle(0);
 
253
                }
 
254
        }
 
255
 
 
256
 
 
257
        //swapremove
 
258
        m_collisionObjects.remove(collisionObject);
 
259
 
 
260
}
 
261
 
 
262
 
 
263
 
 
264
void    btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
 
265
                                                                                btCollisionObject* collisionObject,
 
266
                                                                                const btCollisionShape* collisionShape,
 
267
                                                                                const btTransform& colObjWorldTransform,
 
268
                                                                                RayResultCallback& resultCallback)
 
269
{
 
270
        btSphereShape pointShape(btScalar(0.0));
 
271
        pointShape.setMargin(0.f);
 
272
        const btConvexShape* castShape = &pointShape;
 
273
 
 
274
        if (collisionShape->isConvex())
 
275
        {
 
276
                //              BT_PROFILE("rayTestConvex");
 
277
                btConvexCast::CastResult castResult;
 
278
                castResult.m_fraction = resultCallback.m_closestHitFraction;
 
279
 
 
280
                btConvexShape* convexShape = (btConvexShape*) collisionShape;
 
281
                btVoronoiSimplexSolver  simplexSolver;
 
282
#define USE_SUBSIMPLEX_CONVEX_CAST 1
 
283
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
 
284
                btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
 
285
#else
 
286
                //btGjkConvexCast       convexCaster(castShape,convexShape,&simplexSolver);
 
287
                //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
 
288
#endif //#USE_SUBSIMPLEX_CONVEX_CAST
 
289
 
 
290
                if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
 
291
                {
 
292
                        //add hit
 
293
                        if (castResult.m_normal.length2() > btScalar(0.0001))
 
294
                        {
 
295
                                if (castResult.m_fraction < resultCallback.m_closestHitFraction)
 
296
                                {
 
297
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
 
298
                                        //rotate normal into worldspace
 
299
                                        castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
 
300
#endif //USE_SUBSIMPLEX_CONVEX_CAST
 
301
 
 
302
                                        castResult.m_normal.normalize();
 
303
                                        btCollisionWorld::LocalRayResult localRayResult
 
304
                                                (
 
305
                                                collisionObject,
 
306
                                                0,
 
307
                                                castResult.m_normal,
 
308
                                                castResult.m_fraction
 
309
                                                );
 
310
 
 
311
                                        bool normalInWorldSpace = true;
 
312
                                        resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
 
313
 
 
314
                                }
 
315
                        }
 
316
                }
 
317
        } else {
 
318
                if (collisionShape->isConcave())
 
319
                {
 
320
                        //                      BT_PROFILE("rayTestConcave");
 
321
                        if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
 
322
                        {
 
323
                                ///optimized version for btBvhTriangleMeshShape
 
324
                                btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
 
325
                                btTransform worldTocollisionObject = colObjWorldTransform.inverse();
 
326
                                btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
 
327
                                btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
 
328
 
 
329
                                //ConvexCast::CastResult
 
330
                                struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
 
331
                                {
 
332
                                        btCollisionWorld::RayResultCallback* m_resultCallback;
 
333
                                        btCollisionObject*      m_collisionObject;
 
334
                                        btTriangleMeshShape*    m_triangleMesh;
 
335
 
 
336
                                        btTransform m_colObjWorldTransform;
 
337
 
 
338
                                        BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
 
339
                                                btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*    triangleMesh,const btTransform& colObjWorldTransform):
 
340
                                        //@BP Mod
 
341
                                        btTriangleRaycastCallback(from,to, resultCallback->m_flags),
 
342
                                                m_resultCallback(resultCallback),
 
343
                                                m_collisionObject(collisionObject),
 
344
                                                m_triangleMesh(triangleMesh),
 
345
                                                m_colObjWorldTransform(colObjWorldTransform)
 
346
                                        {
 
347
                                        }
 
348
 
 
349
 
 
350
                                        virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
 
351
                                        {
 
352
                                                btCollisionWorld::LocalShapeInfo        shapeInfo;
 
353
                                                shapeInfo.m_shapePart = partId;
 
354
                                                shapeInfo.m_triangleIndex = triangleIndex;
 
355
 
 
356
                                                btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
 
357
 
 
358
                                                btCollisionWorld::LocalRayResult rayResult
 
359
                                                        (m_collisionObject,
 
360
                                                        &shapeInfo,
 
361
                                                        hitNormalWorld,
 
362
                                                        hitFraction);
 
363
 
 
364
                                                bool    normalInWorldSpace = true;
 
365
                                                return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
 
366
                                        }
 
367
 
 
368
                                };
 
369
 
 
370
                                BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
 
371
                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
372
                                triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
 
373
                        } else
 
374
                        {
 
375
                                //generic (slower) case
 
376
                                btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
 
377
 
 
378
                                btTransform worldTocollisionObject = colObjWorldTransform.inverse();
 
379
 
 
380
                                btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
 
381
                                btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
 
382
 
 
383
                                //ConvexCast::CastResult
 
384
 
 
385
                                struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
 
386
                                {
 
387
                                        btCollisionWorld::RayResultCallback* m_resultCallback;
 
388
                                        btCollisionObject*      m_collisionObject;
 
389
                                        btConcaveShape* m_triangleMesh;
 
390
 
 
391
                                        btTransform m_colObjWorldTransform;
 
392
 
 
393
                                        BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
 
394
                                                btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
 
395
                                        //@BP Mod
 
396
                                        btTriangleRaycastCallback(from,to, resultCallback->m_flags),
 
397
                                                m_resultCallback(resultCallback),
 
398
                                                m_collisionObject(collisionObject),
 
399
                                                m_triangleMesh(triangleMesh),
 
400
                                                m_colObjWorldTransform(colObjWorldTransform)
 
401
                                        {
 
402
                                        }
 
403
 
 
404
 
 
405
                                        virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
 
406
                                        {
 
407
                                                btCollisionWorld::LocalShapeInfo        shapeInfo;
 
408
                                                shapeInfo.m_shapePart = partId;
 
409
                                                shapeInfo.m_triangleIndex = triangleIndex;
 
410
 
 
411
                                                btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
 
412
 
 
413
                                                btCollisionWorld::LocalRayResult rayResult
 
414
                                                        (m_collisionObject,
 
415
                                                        &shapeInfo,
 
416
                                                        hitNormalWorld,
 
417
                                                        hitFraction);
 
418
 
 
419
                                                bool    normalInWorldSpace = true;
 
420
                                                return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
 
421
                                        }
 
422
 
 
423
                                };
 
424
 
 
425
 
 
426
                                BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
 
427
                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
428
 
 
429
                                btVector3 rayAabbMinLocal = rayFromLocal;
 
430
                                rayAabbMinLocal.setMin(rayToLocal);
 
431
                                btVector3 rayAabbMaxLocal = rayFromLocal;
 
432
                                rayAabbMaxLocal.setMax(rayToLocal);
 
433
 
 
434
                                concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
 
435
                        }
 
436
                } else {
 
437
                        //                      BT_PROFILE("rayTestCompound");
 
438
                        if (collisionShape->isCompound())
 
439
                        {
 
440
                                struct LocalInfoAdder2 : public RayResultCallback
 
441
                                {
 
442
                                        RayResultCallback* m_userCallback;
 
443
                                        int m_i;
 
444
                                        
 
445
                                        LocalInfoAdder2 (int i, RayResultCallback *user)
 
446
                                                : m_userCallback(user), m_i(i)
 
447
                                        { 
 
448
                                                m_closestHitFraction = m_userCallback->m_closestHitFraction;
 
449
                                        }
 
450
                                        virtual bool needsCollision(btBroadphaseProxy* p) const
 
451
                                        {
 
452
                                                return m_userCallback->needsCollision(p);
 
453
                                        }
 
454
 
 
455
                                        virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
 
456
                                        {
 
457
                                                btCollisionWorld::LocalShapeInfo shapeInfo;
 
458
                                                shapeInfo.m_shapePart = -1;
 
459
                                                shapeInfo.m_triangleIndex = m_i;
 
460
                                                if (r.m_localShapeInfo == NULL)
 
461
                                                        r.m_localShapeInfo = &shapeInfo;
 
462
 
 
463
                                                const btScalar result = m_userCallback->addSingleResult(r, b);
 
464
                                                m_closestHitFraction = m_userCallback->m_closestHitFraction;
 
465
                                                return result;
 
466
                                        }
 
467
                                };
 
468
                                
 
469
                                struct RayTester : btDbvt::ICollide
 
470
                                {
 
471
                                        btCollisionObject* m_collisionObject;
 
472
                                        const btCompoundShape* m_compoundShape;
 
473
                                        const btTransform& m_colObjWorldTransform;
 
474
                                        const btTransform& m_rayFromTrans;
 
475
                                        const btTransform& m_rayToTrans;
 
476
                                        RayResultCallback& m_resultCallback;
 
477
                                        
 
478
                                        RayTester(btCollisionObject* collisionObject,
 
479
                                                        const btCompoundShape* compoundShape,
 
480
                                                        const btTransform& colObjWorldTransform,
 
481
                                                        const btTransform& rayFromTrans,
 
482
                                                        const btTransform& rayToTrans,
 
483
                                                        RayResultCallback& resultCallback):
 
484
                                                m_collisionObject(collisionObject),
 
485
                                                m_compoundShape(compoundShape),
 
486
                                                m_colObjWorldTransform(colObjWorldTransform),
 
487
                                                m_rayFromTrans(rayFromTrans),
 
488
                                                m_rayToTrans(rayToTrans),
 
489
                                                m_resultCallback(resultCallback)
 
490
                                        {
 
491
                                                
 
492
                                        }
 
493
                                        
 
494
                                        void Process(int i)
 
495
                                        {
 
496
                                                const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
 
497
                                                const btTransform& childTrans = m_compoundShape->getChildTransform(i);
 
498
                                                btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
 
499
                                                
 
500
                                                // replace collision shape so that callback can determine the triangle
 
501
                                                btCollisionShape* saveCollisionShape = m_collisionObject->getCollisionShape();
 
502
                                                m_collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
 
503
 
 
504
                                                LocalInfoAdder2 my_cb(i, &m_resultCallback);
 
505
 
 
506
                                                rayTestSingle(
 
507
                                                        m_rayFromTrans,
 
508
                                                        m_rayToTrans,
 
509
                                                        m_collisionObject,
 
510
                                                        childCollisionShape,
 
511
                                                        childWorldTrans,
 
512
                                                        my_cb);
 
513
                                                
 
514
                                                // restore
 
515
                                                m_collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
 
516
                                        }
 
517
                                        
 
518
                                        void Process(const btDbvtNode* leaf)
 
519
                                        {
 
520
                                                Process(leaf->dataAsInt);
 
521
                                        }
 
522
                                };
 
523
                                
 
524
                                const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
 
525
                                const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
 
526
 
 
527
 
 
528
                                RayTester rayCB(
 
529
                                        collisionObject,
 
530
                                        compoundShape,
 
531
                                        colObjWorldTransform,
 
532
                                        rayFromTrans,
 
533
                                        rayToTrans,
 
534
                                        resultCallback);
 
535
#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
 
536
                                if (dbvt)
 
537
                                {
 
538
                                        btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
 
539
                                        btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
 
540
                                        btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
 
541
                                }
 
542
                                else
 
543
#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
 
544
                                {
 
545
                                        for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
 
546
                                        {
 
547
                                                rayCB.Process(i);
 
548
                                        }       
 
549
                                }
 
550
                        }
 
551
                }
 
552
        }
 
553
}
 
554
 
 
555
void    btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
 
556
                                                                                        btCollisionObject* collisionObject,
 
557
                                                                                        const btCollisionShape* collisionShape,
 
558
                                                                                        const btTransform& colObjWorldTransform,
 
559
                                                                                        ConvexResultCallback& resultCallback, btScalar allowedPenetration)
 
560
{
 
561
        if (collisionShape->isConvex())
 
562
        {
 
563
                //BT_PROFILE("convexSweepConvex");
 
564
                btConvexCast::CastResult castResult;
 
565
                castResult.m_allowedPenetration = allowedPenetration;
 
566
                castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
 
567
 
 
568
                btConvexShape* convexShape = (btConvexShape*) collisionShape;
 
569
                btVoronoiSimplexSolver  simplexSolver;
 
570
                btGjkEpaPenetrationDepthSolver  gjkEpaPenetrationSolver;
 
571
 
 
572
                btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
 
573
                //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
 
574
                //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
 
575
 
 
576
                btConvexCast* castPtr = &convexCaster1;
 
577
 
 
578
 
 
579
 
 
580
                if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
 
581
                {
 
582
                        //add hit
 
583
                        if (castResult.m_normal.length2() > btScalar(0.0001))
 
584
                        {
 
585
                                if (castResult.m_fraction < resultCallback.m_closestHitFraction)
 
586
                                {
 
587
                                        castResult.m_normal.normalize();
 
588
                                        btCollisionWorld::LocalConvexResult localConvexResult
 
589
                                                (
 
590
                                                collisionObject,
 
591
                                                0,
 
592
                                                castResult.m_normal,
 
593
                                                castResult.m_hitPoint,
 
594
                                                castResult.m_fraction
 
595
                                                );
 
596
 
 
597
                                        bool normalInWorldSpace = true;
 
598
                                        resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
 
599
 
 
600
                                }
 
601
                        }
 
602
                }
 
603
        } else {
 
604
                if (collisionShape->isConcave())
 
605
                {
 
606
                        if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
 
607
                        {
 
608
                                //BT_PROFILE("convexSweepbtBvhTriangleMesh");
 
609
                                btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
 
610
                                btTransform worldTocollisionObject = colObjWorldTransform.inverse();
 
611
                                btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
 
612
                                btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
 
613
                                // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
 
614
                                btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
 
615
 
 
616
                                //ConvexCast::CastResult
 
617
                                struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
 
618
                                {
 
619
                                        btCollisionWorld::ConvexResultCallback* m_resultCallback;
 
620
                                        btCollisionObject*      m_collisionObject;
 
621
                                        btTriangleMeshShape*    m_triangleMesh;
 
622
 
 
623
                                        BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
 
624
                                                btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
 
625
                                        btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
 
626
                                                m_resultCallback(resultCallback),
 
627
                                                m_collisionObject(collisionObject),
 
628
                                                m_triangleMesh(triangleMesh)
 
629
                                        {
 
630
                                        }
 
631
 
 
632
 
 
633
                                        virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
 
634
                                        {
 
635
                                                btCollisionWorld::LocalShapeInfo        shapeInfo;
 
636
                                                shapeInfo.m_shapePart = partId;
 
637
                                                shapeInfo.m_triangleIndex = triangleIndex;
 
638
                                                if (hitFraction <= m_resultCallback->m_closestHitFraction)
 
639
                                                {
 
640
 
 
641
                                                        btCollisionWorld::LocalConvexResult convexResult
 
642
                                                                (m_collisionObject,
 
643
                                                                &shapeInfo,
 
644
                                                                hitNormalLocal,
 
645
                                                                hitPointLocal,
 
646
                                                                hitFraction);
 
647
 
 
648
                                                        bool    normalInWorldSpace = true;
 
649
 
 
650
 
 
651
                                                        return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
 
652
                                                }
 
653
                                                return hitFraction;
 
654
                                        }
 
655
 
 
656
                                };
 
657
 
 
658
                                BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
 
659
                                tccb.m_hitFraction = resultCallback.m_closestHitFraction;
 
660
                                tccb.m_allowedPenetration = allowedPenetration;
 
661
                                btVector3 boxMinLocal, boxMaxLocal;
 
662
                                castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
 
663
                                triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
 
664
                        } else
 
665
                        {
 
666
                                if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
 
667
                                {
 
668
                                        btConvexCast::CastResult castResult;
 
669
                                        castResult.m_allowedPenetration = allowedPenetration;
 
670
                                        castResult.m_fraction = resultCallback.m_closestHitFraction;
 
671
                                        btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape;
 
672
                                        btContinuousConvexCollision convexCaster1(castShape,planeShape);
 
673
                                        btConvexCast* castPtr = &convexCaster1;
 
674
 
 
675
                                        if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
 
676
                                        {
 
677
                                                //add hit
 
678
                                                if (castResult.m_normal.length2() > btScalar(0.0001))
 
679
                                                {
 
680
                                                        if (castResult.m_fraction < resultCallback.m_closestHitFraction)
 
681
                                                        {
 
682
                                                                castResult.m_normal.normalize();
 
683
                                                                btCollisionWorld::LocalConvexResult localConvexResult
 
684
                                                                        (
 
685
                                                                        collisionObject,
 
686
                                                                        0,
 
687
                                                                        castResult.m_normal,
 
688
                                                                        castResult.m_hitPoint,
 
689
                                                                        castResult.m_fraction
 
690
                                                                        );
 
691
 
 
692
                                                                bool normalInWorldSpace = true;
 
693
                                                                resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
 
694
                                                        }
 
695
                                                }
 
696
                                        }
 
697
 
 
698
                                } else
 
699
                                {
 
700
                                        //BT_PROFILE("convexSweepConcave");
 
701
                                        btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
 
702
                                        btTransform worldTocollisionObject = colObjWorldTransform.inverse();
 
703
                                        btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
 
704
                                        btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
 
705
                                        // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
 
706
                                        btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
 
707
 
 
708
                                        //ConvexCast::CastResult
 
709
                                        struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
 
710
                                        {
 
711
                                                btCollisionWorld::ConvexResultCallback* m_resultCallback;
 
712
                                                btCollisionObject*      m_collisionObject;
 
713
                                                btConcaveShape* m_triangleMesh;
 
714
 
 
715
                                                BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
 
716
                                                        btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*      triangleMesh, const btTransform& triangleToWorld):
 
717
                                                btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
 
718
                                                        m_resultCallback(resultCallback),
 
719
                                                        m_collisionObject(collisionObject),
 
720
                                                        m_triangleMesh(triangleMesh)
 
721
                                                {
 
722
                                                }
 
723
 
 
724
 
 
725
                                                virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
 
726
                                                {
 
727
                                                        btCollisionWorld::LocalShapeInfo        shapeInfo;
 
728
                                                        shapeInfo.m_shapePart = partId;
 
729
                                                        shapeInfo.m_triangleIndex = triangleIndex;
 
730
                                                        if (hitFraction <= m_resultCallback->m_closestHitFraction)
 
731
                                                        {
 
732
 
 
733
                                                                btCollisionWorld::LocalConvexResult convexResult
 
734
                                                                        (m_collisionObject,
 
735
                                                                        &shapeInfo,
 
736
                                                                        hitNormalLocal,
 
737
                                                                        hitPointLocal,
 
738
                                                                        hitFraction);
 
739
 
 
740
                                                                bool    normalInWorldSpace = false;
 
741
 
 
742
                                                                return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
 
743
                                                        }
 
744
                                                        return hitFraction;
 
745
                                                }
 
746
 
 
747
                                        };
 
748
 
 
749
                                        BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
 
750
                                        tccb.m_hitFraction = resultCallback.m_closestHitFraction;
 
751
                                        tccb.m_allowedPenetration = allowedPenetration;
 
752
                                        btVector3 boxMinLocal, boxMaxLocal;
 
753
                                        castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
 
754
 
 
755
                                        btVector3 rayAabbMinLocal = convexFromLocal;
 
756
                                        rayAabbMinLocal.setMin(convexToLocal);
 
757
                                        btVector3 rayAabbMaxLocal = convexFromLocal;
 
758
                                        rayAabbMaxLocal.setMax(convexToLocal);
 
759
                                        rayAabbMinLocal += boxMinLocal;
 
760
                                        rayAabbMaxLocal += boxMaxLocal;
 
761
                                        concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
 
762
                                }
 
763
                        }
 
764
                } else {
 
765
                        ///@todo : use AABB tree or other BVH acceleration structure!
 
766
                        if (collisionShape->isCompound())
 
767
                        {
 
768
                                BT_PROFILE("convexSweepCompound");
 
769
                                const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
 
770
                                int i=0;
 
771
                                for (i=0;i<compoundShape->getNumChildShapes();i++)
 
772
                                {
 
773
                                        btTransform childTrans = compoundShape->getChildTransform(i);
 
774
                                        const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
 
775
                                        btTransform childWorldTrans = colObjWorldTransform * childTrans;
 
776
                                        // replace collision shape so that callback can determine the triangle
 
777
                                        btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
 
778
                                        collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
 
779
                    struct      LocalInfoAdder : public ConvexResultCallback {
 
780
                            ConvexResultCallback* m_userCallback;
 
781
                                                        int m_i;
 
782
 
 
783
                            LocalInfoAdder (int i, ConvexResultCallback *user)
 
784
                                                                : m_userCallback(user), m_i(i)
 
785
                                                        {
 
786
                                                                m_closestHitFraction = m_userCallback->m_closestHitFraction;
 
787
                                                        }
 
788
                                                        virtual bool needsCollision(btBroadphaseProxy* p) const
 
789
                                                        {
 
790
                                                                return m_userCallback->needsCollision(p);
 
791
                                                        }
 
792
                            virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult&      r,      bool b)
 
793
                            {
 
794
                                    btCollisionWorld::LocalShapeInfo    shapeInfo;
 
795
                                    shapeInfo.m_shapePart = -1;
 
796
                                    shapeInfo.m_triangleIndex = m_i;
 
797
                                    if (r.m_localShapeInfo == NULL)
 
798
                                        r.m_localShapeInfo = &shapeInfo;
 
799
                                                                        const btScalar result = m_userCallback->addSingleResult(r, b);
 
800
                                                                        m_closestHitFraction = m_userCallback->m_closestHitFraction;
 
801
                                                                        return result;
 
802
                                    
 
803
                            }
 
804
                    };
 
805
 
 
806
                    LocalInfoAdder my_cb(i, &resultCallback);
 
807
                                        
 
808
 
 
809
                                        objectQuerySingle(castShape, convexFromTrans,convexToTrans,
 
810
                                                collisionObject,
 
811
                                                childCollisionShape,
 
812
                                                childWorldTrans,
 
813
                                                my_cb, allowedPenetration);
 
814
                                        // restore
 
815
                                        collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
 
816
                                }
 
817
                        }
 
818
                }
 
819
        }
 
820
}
 
821
 
 
822
 
 
823
struct btSingleRayCallback : public btBroadphaseRayCallback
 
824
{
 
825
 
 
826
        btVector3       m_rayFromWorld;
 
827
        btVector3       m_rayToWorld;
 
828
        btTransform     m_rayFromTrans;
 
829
        btTransform     m_rayToTrans;
 
830
        btVector3       m_hitNormal;
 
831
 
 
832
        const btCollisionWorld* m_world;
 
833
        btCollisionWorld::RayResultCallback&    m_resultCallback;
 
834
 
 
835
        btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
 
836
                :m_rayFromWorld(rayFromWorld),
 
837
                m_rayToWorld(rayToWorld),
 
838
                m_world(world),
 
839
                m_resultCallback(resultCallback)
 
840
        {
 
841
                m_rayFromTrans.setIdentity();
 
842
                m_rayFromTrans.setOrigin(m_rayFromWorld);
 
843
                m_rayToTrans.setIdentity();
 
844
                m_rayToTrans.setOrigin(m_rayToWorld);
 
845
 
 
846
                btVector3 rayDir = (rayToWorld-rayFromWorld);
 
847
 
 
848
                rayDir.normalize ();
 
849
                ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
 
850
                m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
 
851
                m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
 
852
                m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 
853
                m_signs[0] = m_rayDirectionInverse[0] < 0.0;
 
854
                m_signs[1] = m_rayDirectionInverse[1] < 0.0;
 
855
                m_signs[2] = m_rayDirectionInverse[2] < 0.0;
 
856
 
 
857
                m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
 
858
 
 
859
        }
 
860
 
 
861
 
 
862
 
 
863
        virtual bool    process(const btBroadphaseProxy* proxy)
 
864
        {
 
865
                ///terminate further ray tests, once the closestHitFraction reached zero
 
866
                if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
 
867
                        return false;
 
868
 
 
869
                btCollisionObject*      collisionObject = (btCollisionObject*)proxy->m_clientObject;
 
870
 
 
871
                //only perform raycast if filterMask matches
 
872
                if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
 
873
                {
 
874
                        //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
 
875
                        //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
 
876
#if 0
 
877
#ifdef RECALCULATE_AABB
 
878
                        btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
 
879
                        collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
 
880
#else
 
881
                        //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
 
882
                        const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
 
883
                        const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
 
884
#endif
 
885
#endif
 
886
                        //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
 
887
                        //culling already done by broadphase
 
888
                        //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
 
889
                        {
 
890
                                m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
 
891
                                        collisionObject,
 
892
                                        collisionObject->getCollisionShape(),
 
893
                                        collisionObject->getWorldTransform(),
 
894
                                        m_resultCallback);
 
895
                        }
 
896
                }
 
897
                return true;
 
898
        }
 
899
};
 
900
 
 
901
void    btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
 
902
{
 
903
        //BT_PROFILE("rayTest");
 
904
        /// use the broadphase to accelerate the search for objects, based on their aabb
 
905
        /// and for each object with ray-aabb overlap, perform an exact ray test
 
906
        btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
 
907
 
 
908
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
 
909
        m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
 
910
#else
 
911
        for (int i=0;i<this->getNumCollisionObjects();i++)
 
912
        {
 
913
                rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
 
914
        }       
 
915
#endif //USE_BRUTEFORCE_RAYBROADPHASE
 
916
 
 
917
}
 
918
 
 
919
 
 
920
struct btSingleSweepCallback : public btBroadphaseRayCallback
 
921
{
 
922
 
 
923
        btTransform     m_convexFromTrans;
 
924
        btTransform     m_convexToTrans;
 
925
        btVector3       m_hitNormal;
 
926
        const btCollisionWorld* m_world;
 
927
        btCollisionWorld::ConvexResultCallback& m_resultCallback;
 
928
        btScalar        m_allowedCcdPenetration;
 
929
        const btConvexShape* m_castShape;
 
930
 
 
931
 
 
932
        btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
 
933
                :m_convexFromTrans(convexFromTrans),
 
934
                m_convexToTrans(convexToTrans),
 
935
                m_world(world),
 
936
                m_resultCallback(resultCallback),
 
937
                m_allowedCcdPenetration(allowedPenetration),
 
938
                m_castShape(castShape)
 
939
        {
 
940
                btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
 
941
                btVector3 rayDir = unnormalizedRayDir.normalized();
 
942
                ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
 
943
                m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
 
944
                m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
 
945
                m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 
946
                m_signs[0] = m_rayDirectionInverse[0] < 0.0;
 
947
                m_signs[1] = m_rayDirectionInverse[1] < 0.0;
 
948
                m_signs[2] = m_rayDirectionInverse[2] < 0.0;
 
949
 
 
950
                m_lambda_max = rayDir.dot(unnormalizedRayDir);
 
951
 
 
952
        }
 
953
 
 
954
        virtual bool    process(const btBroadphaseProxy* proxy)
 
955
        {
 
956
                ///terminate further convex sweep tests, once the closestHitFraction reached zero
 
957
                if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
 
958
                        return false;
 
959
 
 
960
                btCollisionObject*      collisionObject = (btCollisionObject*)proxy->m_clientObject;
 
961
 
 
962
                //only perform raycast if filterMask matches
 
963
                if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
 
964
                        //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
 
965
                        m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
 
966
                                collisionObject,
 
967
                                collisionObject->getCollisionShape(),
 
968
                                collisionObject->getWorldTransform(),
 
969
                                m_resultCallback,
 
970
                                m_allowedCcdPenetration);
 
971
                }
 
972
 
 
973
                return true;
 
974
        }
 
975
};
 
976
 
 
977
 
 
978
 
 
979
void    btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
 
980
{
 
981
 
 
982
        BT_PROFILE("convexSweepTest");
 
983
        /// use the broadphase to accelerate the search for objects, based on their aabb
 
984
        /// and for each object with ray-aabb overlap, perform an exact ray test
 
985
        /// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
 
986
 
 
987
 
 
988
 
 
989
        btTransform     convexFromTrans,convexToTrans;
 
990
        convexFromTrans = convexFromWorld;
 
991
        convexToTrans = convexToWorld;
 
992
        btVector3 castShapeAabbMin, castShapeAabbMax;
 
993
        /* Compute AABB that encompasses angular movement */
 
994
        {
 
995
                btVector3 linVel, angVel;
 
996
                btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
 
997
                btVector3 zeroLinVel;
 
998
                zeroLinVel.setValue(0,0,0);
 
999
                btTransform R;
 
1000
                R.setIdentity ();
 
1001
                R.setRotation (convexFromTrans.getRotation());
 
1002
                castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
 
1003
        }
 
1004
 
 
1005
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
 
1006
 
 
1007
        btSingleSweepCallback   convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
 
1008
 
 
1009
        m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
 
1010
 
 
1011
#else
 
1012
        /// go over all objects, and if the ray intersects their aabb + cast shape aabb,
 
1013
        // do a ray-shape query using convexCaster (CCD)
 
1014
        int i;
 
1015
        for (i=0;i<m_collisionObjects.size();i++)
 
1016
        {
 
1017
                btCollisionObject*      collisionObject= m_collisionObjects[i];
 
1018
                //only perform raycast if filterMask matches
 
1019
                if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
 
1020
                        //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
 
1021
                        btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
 
1022
                        collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
 
1023
                        AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
 
1024
                        btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
 
1025
                        btVector3 hitNormal;
 
1026
                        if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
 
1027
                        {
 
1028
                                objectQuerySingle(castShape, convexFromTrans,convexToTrans,
 
1029
                                        collisionObject,
 
1030
                                        collisionObject->getCollisionShape(),
 
1031
                                        collisionObject->getWorldTransform(),
 
1032
                                        resultCallback,
 
1033
                                        allowedCcdPenetration);
 
1034
                        }
 
1035
                }
 
1036
        }
 
1037
#endif //USE_BRUTEFORCE_RAYBROADPHASE
 
1038
}
 
1039
 
 
1040
 
 
1041
 
 
1042
struct btBridgedManifoldResult : public btManifoldResult
 
1043
{
 
1044
 
 
1045
        btCollisionWorld::ContactResultCallback&        m_resultCallback;
 
1046
 
 
1047
        btBridgedManifoldResult( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
 
1048
                :btManifoldResult(obj0,obj1),
 
1049
                m_resultCallback(resultCallback)
 
1050
        {
 
1051
        }
 
1052
 
 
1053
        virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
 
1054
        {
 
1055
                bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
 
1056
                btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
 
1057
                btVector3 localA;
 
1058
                btVector3 localB;
 
1059
                if (isSwapped)
 
1060
                {
 
1061
                        localA = m_rootTransB.invXform(pointA );
 
1062
                        localB = m_rootTransA.invXform(pointInWorld);
 
1063
                } else
 
1064
                {
 
1065
                        localA = m_rootTransA.invXform(pointA );
 
1066
                        localB = m_rootTransB.invXform(pointInWorld);
 
1067
                }
 
1068
                
 
1069
                btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
 
1070
                newPt.m_positionWorldOnA = pointA;
 
1071
                newPt.m_positionWorldOnB = pointInWorld;
 
1072
                
 
1073
           //BP mod, store contact triangles.
 
1074
                if (isSwapped)
 
1075
                {
 
1076
                        newPt.m_partId0 = m_partId1;
 
1077
                        newPt.m_partId1 = m_partId0;
 
1078
                        newPt.m_index0  = m_index1;
 
1079
                        newPt.m_index1  = m_index0;
 
1080
                } else
 
1081
                {
 
1082
                        newPt.m_partId0 = m_partId0;
 
1083
                        newPt.m_partId1 = m_partId1;
 
1084
                        newPt.m_index0  = m_index0;
 
1085
                        newPt.m_index1  = m_index1;
 
1086
                }
 
1087
 
 
1088
                //experimental feature info, for per-triangle material etc.
 
1089
                btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
 
1090
                btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
 
1091
                m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
 
1092
 
 
1093
        }
 
1094
        
 
1095
};
 
1096
 
 
1097
 
 
1098
 
 
1099
struct btSingleContactCallback : public btBroadphaseAabbCallback
 
1100
{
 
1101
 
 
1102
        btCollisionObject* m_collisionObject;
 
1103
        btCollisionWorld*       m_world;
 
1104
        btCollisionWorld::ContactResultCallback&        m_resultCallback;
 
1105
        
 
1106
        
 
1107
        btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
 
1108
                :m_collisionObject(collisionObject),
 
1109
                m_world(world),
 
1110
                m_resultCallback(resultCallback)
 
1111
        {
 
1112
        }
 
1113
 
 
1114
        virtual bool    process(const btBroadphaseProxy* proxy)
 
1115
        {
 
1116
                btCollisionObject*      collisionObject = (btCollisionObject*)proxy->m_clientObject;
 
1117
                if (collisionObject == m_collisionObject)
 
1118
                        return true;
 
1119
 
 
1120
                //only perform raycast if filterMask matches
 
1121
                if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
 
1122
                {
 
1123
                        btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
 
1124
                        if (algorithm)
 
1125
                        {
 
1126
                                btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
 
1127
                                //discrete collision detection query
 
1128
                                algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);
 
1129
 
 
1130
                                algorithm->~btCollisionAlgorithm();
 
1131
                                m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
 
1132
                        }
 
1133
                }
 
1134
                return true;
 
1135
        }
 
1136
};
 
1137
 
 
1138
 
 
1139
///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback.
 
1140
///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
 
1141
void    btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback)
 
1142
{
 
1143
        btVector3 aabbMin,aabbMax;
 
1144
        colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
 
1145
        btSingleContactCallback contactCB(colObj,this,resultCallback);
 
1146
        
 
1147
        m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
 
1148
}
 
1149
 
 
1150
 
 
1151
///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
 
1152
///it reports one or more contact points (including the one with deepest penetration)
 
1153
void    btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
 
1154
{
 
1155
        btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
 
1156
        if (algorithm)
 
1157
        {
 
1158
                btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
 
1159
                //discrete collision detection query
 
1160
                algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);
 
1161
 
 
1162
                algorithm->~btCollisionAlgorithm();
 
1163
                getDispatcher()->freeCollisionAlgorithm(algorithm);
 
1164
        }
 
1165
 
 
1166
}
 
1167
 
 
1168
 
 
1169
 
 
1170
 
 
1171
class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
 
1172
{
 
1173
        btIDebugDraw*   m_debugDrawer;
 
1174
        btVector3       m_color;
 
1175
        btTransform     m_worldTrans;
 
1176
 
 
1177
public:
 
1178
 
 
1179
        DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
 
1180
          m_debugDrawer(debugDrawer),
 
1181
                  m_color(color),
 
1182
                  m_worldTrans(worldTrans)
 
1183
          {
 
1184
          }
 
1185
 
 
1186
          virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
 
1187
          {
 
1188
                  processTriangle(triangle,partId,triangleIndex);
 
1189
          }
 
1190
 
 
1191
          virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
 
1192
          {
 
1193
                  (void)partId;
 
1194
                  (void)triangleIndex;
 
1195
 
 
1196
                  btVector3 wv0,wv1,wv2;
 
1197
                  wv0 = m_worldTrans*triangle[0];
 
1198
                  wv1 = m_worldTrans*triangle[1];
 
1199
                  wv2 = m_worldTrans*triangle[2];
 
1200
                  btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
 
1201
 
 
1202
                  btVector3 normal = (wv1-wv0).cross(wv2-wv0);
 
1203
                  normal.normalize();
 
1204
                  btVector3 normalColor(1,1,0);
 
1205
                  m_debugDrawer->drawLine(center,center+normal,normalColor);
 
1206
 
 
1207
 
 
1208
 
 
1209
                 
 
1210
                  m_debugDrawer->drawLine(wv0,wv1,m_color);
 
1211
                  m_debugDrawer->drawLine(wv1,wv2,m_color);
 
1212
                  m_debugDrawer->drawLine(wv2,wv0,m_color);
 
1213
          }
 
1214
};
 
1215
 
 
1216
 
 
1217
void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
 
1218
{
 
1219
        // Draw a small simplex at the center of the object
 
1220
        getDebugDrawer()->drawTransform(worldTransform,1);
 
1221
 
 
1222
        if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
 
1223
        {
 
1224
                const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
 
1225
                for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
 
1226
                {
 
1227
                        btTransform childTrans = compoundShape->getChildTransform(i);
 
1228
                        const btCollisionShape* colShape = compoundShape->getChildShape(i);
 
1229
                        debugDrawObject(worldTransform*childTrans,colShape,color);
 
1230
                }
 
1231
 
 
1232
        } else
 
1233
        {
 
1234
                switch (shape->getShapeType())
 
1235
                {
 
1236
 
 
1237
                case BOX_SHAPE_PROXYTYPE:
 
1238
                        {
 
1239
                                const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
 
1240
                                btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
 
1241
                                getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
 
1242
                                break;
 
1243
                        }
 
1244
 
 
1245
                case SPHERE_SHAPE_PROXYTYPE:
 
1246
                        {
 
1247
                                const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
 
1248
                                btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
 
1249
 
 
1250
                                getDebugDrawer()->drawSphere(radius, worldTransform, color);
 
1251
                                break;
 
1252
                        }
 
1253
                case MULTI_SPHERE_SHAPE_PROXYTYPE:
 
1254
                        {
 
1255
                                const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
 
1256
 
 
1257
                                btTransform childTransform;
 
1258
                                childTransform.setIdentity();
 
1259
 
 
1260
                                for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
 
1261
                                {
 
1262
                                        childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
 
1263
                                        getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
 
1264
                                }
 
1265
 
 
1266
                                break;
 
1267
                        }
 
1268
                case CAPSULE_SHAPE_PROXYTYPE:
 
1269
                        {
 
1270
                                const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
 
1271
 
 
1272
                                btScalar radius = capsuleShape->getRadius();
 
1273
                                btScalar halfHeight = capsuleShape->getHalfHeight();
 
1274
 
 
1275
                                int upAxis = capsuleShape->getUpAxis();
 
1276
                                getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
 
1277
                                break;
 
1278
                        }
 
1279
                case CONE_SHAPE_PROXYTYPE:
 
1280
                        {
 
1281
                                const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
 
1282
                                btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
 
1283
                                btScalar height = coneShape->getHeight();//+coneShape->getMargin();
 
1284
 
 
1285
                                int upAxis= coneShape->getConeUpIndex();
 
1286
                                getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
 
1287
                                break;
 
1288
 
 
1289
                        }
 
1290
                case CYLINDER_SHAPE_PROXYTYPE:
 
1291
                        {
 
1292
                                const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
 
1293
                                int upAxis = cylinder->getUpAxis();
 
1294
                                btScalar radius = cylinder->getRadius();
 
1295
                                btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
 
1296
                                getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
 
1297
                                break;
 
1298
                        }
 
1299
 
 
1300
                case STATIC_PLANE_PROXYTYPE:
 
1301
                        {
 
1302
                                const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
 
1303
                                btScalar planeConst = staticPlaneShape->getPlaneConstant();
 
1304
                                const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
 
1305
                                getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
 
1306
                                break;
 
1307
 
 
1308
                        }
 
1309
                default:
 
1310
                        {
 
1311
 
 
1312
                                if (shape->isConcave())
 
1313
                                {
 
1314
                                        btConcaveShape* concaveMesh = (btConcaveShape*) shape;
 
1315
 
 
1316
                                        ///@todo pass camera, for some culling? no -> we are not a graphics lib
 
1317
                                        btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 
1318
                                        btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
 
1319
 
 
1320
                                        DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
 
1321
                                        concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
 
1322
 
 
1323
                                }
 
1324
 
 
1325
                                if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
 
1326
                                {
 
1327
                                        btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
 
1328
                                        //todo: pass camera for some culling                    
 
1329
                                        btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 
1330
                                        btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
 
1331
                                        //DebugDrawcallback drawCallback;
 
1332
                                        DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
 
1333
                                        convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
 
1334
                                }
 
1335
 
 
1336
 
 
1337
                                /// for polyhedral shapes
 
1338
                                if (shape->isPolyhedral())
 
1339
                                {
 
1340
                                        btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
 
1341
 
 
1342
                                        int i;
 
1343
                                        if (polyshape->getConvexPolyhedron())
 
1344
                                        {
 
1345
                                                const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
 
1346
                                                for (i=0;i<poly->m_faces.size();i++)
 
1347
                                                {
 
1348
                                                        btVector3 centroid(0,0,0);
 
1349
                                                        int numVerts = poly->m_faces[i].m_indices.size();
 
1350
                                                        if (numVerts)
 
1351
                                                        {
 
1352
                                                                int lastV = poly->m_faces[i].m_indices[numVerts-1];
 
1353
                                                                for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
 
1354
                                                                {
 
1355
                                                                        int curVert = poly->m_faces[i].m_indices[v];
 
1356
                                                                        centroid+=poly->m_vertices[curVert];
 
1357
                                                                        getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
 
1358
                                                                        lastV = curVert;
 
1359
                                                                }
 
1360
                                                        }
 
1361
                                                        centroid*= 1./btScalar(numVerts);
 
1362
 
 
1363
                                                        btVector3 normalColor(1,1,0);
 
1364
                                                        btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
 
1365
                                                        getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
 
1366
                                                        
 
1367
                                                        
 
1368
                                                }
 
1369
 
 
1370
                                                
 
1371
                                        } else
 
1372
                                        {
 
1373
                                                for (i=0;i<polyshape->getNumEdges();i++)
 
1374
                                                {
 
1375
                                                        btVector3 a,b;
 
1376
                                                        polyshape->getEdge(i,a,b);
 
1377
                                                        btVector3 wa = worldTransform * a;
 
1378
                                                        btVector3 wb = worldTransform * b;
 
1379
                                                        getDebugDrawer()->drawLine(wa,wb,color);
 
1380
                                                }
 
1381
                                        }
 
1382
 
 
1383
 
 
1384
                                }
 
1385
                        }
 
1386
                }
 
1387
        }
 
1388
}
 
1389
 
 
1390
 
 
1391
void    btCollisionWorld::debugDrawWorld()
 
1392
{
 
1393
        if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
 
1394
        {
 
1395
                int numManifolds = getDispatcher()->getNumManifolds();
 
1396
                btVector3 color(0,0,0);
 
1397
                for (int i=0;i<numManifolds;i++)
 
1398
                {
 
1399
                        btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
 
1400
                        //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
 
1401
                        //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
 
1402
 
 
1403
                        int numContacts = contactManifold->getNumContacts();
 
1404
                        for (int j=0;j<numContacts;j++)
 
1405
                        {
 
1406
                                btManifoldPoint& cp = contactManifold->getContactPoint(j);
 
1407
                                getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
 
1408
                        }
 
1409
                }
 
1410
        }
 
1411
 
 
1412
        if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
 
1413
        {
 
1414
                int i;
 
1415
 
 
1416
                for (  i=0;i<m_collisionObjects.size();i++)
 
1417
                {
 
1418
                        btCollisionObject* colObj = m_collisionObjects[i];
 
1419
                        if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
 
1420
                        {
 
1421
                                if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
 
1422
                                {
 
1423
                                        btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
 
1424
                                        switch(colObj->getActivationState())
 
1425
                                        {
 
1426
                                        case  ACTIVE_TAG:
 
1427
                                                color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
 
1428
                                        case ISLAND_SLEEPING:
 
1429
                                                color =  btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
 
1430
                                        case WANTS_DEACTIVATION:
 
1431
                                                color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
 
1432
                                        case DISABLE_DEACTIVATION:
 
1433
                                                color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
 
1434
                                        case DISABLE_SIMULATION:
 
1435
                                                color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
 
1436
                                        default:
 
1437
                                                {
 
1438
                                                        color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
 
1439
                                                }
 
1440
                                        };
 
1441
 
 
1442
                                        debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
 
1443
                                }
 
1444
                                if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
 
1445
                                {
 
1446
                                        btVector3 minAabb,maxAabb;
 
1447
                                        btVector3 colorvec(1,0,0);
 
1448
                                        colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
 
1449
                                        btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
 
1450
                                        minAabb -= contactThreshold;
 
1451
                                        maxAabb += contactThreshold;
 
1452
 
 
1453
                                        btVector3 minAabb2,maxAabb2;
 
1454
 
 
1455
                                        if(colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
 
1456
                                        {
 
1457
                                                colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
 
1458
                                                minAabb2 -= contactThreshold;
 
1459
                                                maxAabb2 += contactThreshold;
 
1460
                                                minAabb.setMin(minAabb2);
 
1461
                                                maxAabb.setMax(maxAabb2);
 
1462
                                        }
 
1463
 
 
1464
                                        m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
 
1465
                                }
 
1466
                        }
 
1467
 
 
1468
                }
 
1469
        }
 
1470
}
 
1471
 
 
1472
 
 
1473
void    btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
 
1474
{
 
1475
        int i;
 
1476
        //serialize all collision objects
 
1477
        for (i=0;i<m_collisionObjects.size();i++)
 
1478
        {
 
1479
                btCollisionObject* colObj = m_collisionObjects[i];
 
1480
                if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
 
1481
                {
 
1482
                        colObj->serializeSingleObject(serializer);
 
1483
                }
 
1484
        }
 
1485
 
 
1486
        ///keep track of shapes already serialized
 
1487
        btHashMap<btHashPtr,btCollisionShape*>  serializedShapes;
 
1488
 
 
1489
        for (i=0;i<m_collisionObjects.size();i++)
 
1490
        {
 
1491
                btCollisionObject* colObj = m_collisionObjects[i];
 
1492
                btCollisionShape* shape = colObj->getCollisionShape();
 
1493
 
 
1494
                if (!serializedShapes.find(shape))
 
1495
                {
 
1496
                        serializedShapes.insert(shape,shape);
 
1497
                        shape->serializeSingleShape(serializer);
 
1498
                }
 
1499
        }
 
1500
 
 
1501
}
 
1502
 
 
1503
 
 
1504
void    btCollisionWorld::serialize(btSerializer* serializer)
 
1505
{
 
1506
 
 
1507
        serializer->startSerialization();
 
1508
        
 
1509
        serializeCollisionObjects(serializer);
 
1510
        
 
1511
        serializer->finishSerialization();
 
1512
}
 
1513