2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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:
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.
17
#include "btContinuousConvexCollision.h"
18
#include "BulletCollision/CollisionShapes/btConvexShape.h"
19
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
20
#include "LinearMath/btTransformUtil.h"
21
#include "BulletCollision/CollisionShapes/btSphereShape.h"
23
#include "btGjkPairDetector.h"
24
#include "btPointCollector.h"
25
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
29
btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver)
30
:m_simplexSolver(simplexSolver),
31
m_penetrationDepthSolver(penetrationDepthSolver),
32
m_convexA(convexA),m_convexB1(convexB),m_planeShape(0)
37
btContinuousConvexCollision::btContinuousConvexCollision( const btConvexShape* convexA,const btStaticPlaneShape* plane)
39
m_penetrationDepthSolver(0),
40
m_convexA(convexA),m_convexB1(0),m_planeShape(plane)
45
/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
46
/// You don't want your game ever to lock-up.
47
#define MAX_ITERATIONS 64
49
void btContinuousConvexCollision::computeClosestPoints( const btTransform& transA, const btTransform& transB,btPointCollector& pointCollector)
53
m_simplexSolver->reset();
54
btGjkPairDetector gjk(m_convexA,m_convexB1,m_convexA->getShapeType(),m_convexB1->getShapeType(),m_convexA->getMargin(),m_convexB1->getMargin(),m_simplexSolver,m_penetrationDepthSolver);
55
btGjkPairDetector::ClosestPointInput input;
56
input.m_transformA = transA;
57
input.m_transformB = transB;
58
gjk.getClosestPoints(input,pointCollector,0);
62
const btConvexShape* convexShape = m_convexA;
63
const btStaticPlaneShape* planeShape = m_planeShape;
65
bool hasCollision = false;
66
const btVector3& planeNormal = planeShape->getPlaneNormal();
67
const btScalar& planeConstant = planeShape->getPlaneConstant();
69
btTransform convexWorldTransform = transA;
70
btTransform convexInPlaneTrans;
71
convexInPlaneTrans= transB.inverse() * convexWorldTransform;
72
btTransform planeInConvex;
73
planeInConvex= convexWorldTransform.inverse() * transB;
75
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
77
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
78
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
80
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
81
btVector3 vtxInPlaneWorld = transB * vtxInPlaneProjected;
82
btVector3 normalOnSurfaceB = transB.getBasis() * planeNormal;
84
pointCollector.addContactPoint(
91
bool btContinuousConvexCollision::calcTimeOfImpact(
92
const btTransform& fromA,
93
const btTransform& toA,
94
const btTransform& fromB,
95
const btTransform& toB,
100
/// compute linear and angular velocity for this interval, to interpolate
101
btVector3 linVelA,angVelA,linVelB,angVelB;
102
btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
103
btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);
106
btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
107
btScalar boundingRadiusB = m_convexB1?m_convexB1->getAngularMotionDisc():0.f;
109
btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
110
btVector3 relLinVel = (linVelB-linVelA);
112
btScalar relLinVelocLength = (linVelB-linVelA).length();
114
if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f)
119
btScalar lambda = btScalar(0.);
122
int maxIter = MAX_ITERATIONS;
125
n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
126
bool hasResult = false;
129
btScalar lastLambda = lambda;
130
//btScalar epsilon = btScalar(0.001);
133
//first solution, using GJK
136
btScalar radius = 0.001f;
137
// result.drawCoordSystem(sphereTr);
139
btPointCollector pointCollector1;
143
computeClosestPoints(fromA,fromB,pointCollector1);
145
hasResult = pointCollector1.m_hasResult;
146
c = pointCollector1.m_pointInWorld;
152
dist = pointCollector1.m_distance + result.m_allowedPenetration;
153
n = pointCollector1.m_normalOnBInWorld;
154
btScalar projectedLinearVelocity = relLinVel.dot(n);
155
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
159
while (dist > radius)
161
if (result.m_debugDrawer)
163
result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1));
165
btScalar dLambda = btScalar(0.);
167
projectedLinearVelocity = relLinVel.dot(n);
170
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
171
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
174
dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
178
lambda = lambda + dLambda;
180
if (lambda > btScalar(1.))
183
if (lambda < btScalar(0.))
187
//todo: next check with relative epsilon
188
if (lambda <= lastLambda)
198
//interpolate to next lambda
199
btTransform interpolatedTransA,interpolatedTransB,relativeTrans;
201
btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
202
btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
203
relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
205
if (result.m_debugDrawer)
207
result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(),0.2f,btVector3(1,0,0));
210
result.DebugDraw( lambda );
212
btPointCollector pointCollector;
213
computeClosestPoints(interpolatedTransA,interpolatedTransB,pointCollector);
215
if (pointCollector.m_hasResult)
217
dist = pointCollector.m_distance+result.m_allowedPenetration;
218
c = pointCollector.m_pointInWorld;
219
n = pointCollector.m_normalOnBInWorld;
222
result.reportFailure(-1, numIter);
227
if (numIter > maxIter)
229
result.reportFailure(-2, numIter);
234
result.m_fraction = lambda;
236
result.m_hitPoint = c;