Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 00014 */ 00015 00016 #include "btConvex2dConvex2dAlgorithm.h" 00017 00018 //#include <stdio.h> 00019 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" 00020 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" 00021 #include "BulletCollision/CollisionDispatch/btCollisionObject.h" 00022 #include "BulletCollision/CollisionShapes/btConvexShape.h" 00023 #include "BulletCollision/CollisionShapes/btCapsuleShape.h" 00024 00025 00026 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" 00027 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 00028 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" 00029 #include "BulletCollision/CollisionShapes/btBoxShape.h" 00030 #include "BulletCollision/CollisionDispatch/btManifoldResult.h" 00031 00032 #include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" 00033 #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" 00034 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" 00035 #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" 00036 00037 00038 00039 #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" 00040 #include "BulletCollision/CollisionShapes/btSphereShape.h" 00041 00042 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" 00043 00044 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" 00045 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" 00046 00047 00048 btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) 00049 { 00050 m_numPerturbationIterations = 0; 00051 m_minimumPointsPerturbationThreshold = 3; 00052 m_simplexSolver = simplexSolver; 00053 m_pdSolver = pdSolver; 00054 } 00055 00056 btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() 00057 { 00058 } 00059 00060 btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold) 00061 : btActivatingCollisionAlgorithm(ci,body0,body1), 00062 m_simplexSolver(simplexSolver), 00063 m_pdSolver(pdSolver), 00064 m_ownManifold (false), 00065 m_manifoldPtr(mf), 00066 m_lowLevelOfDetail(false), 00067 m_numPerturbationIterations(numPerturbationIterations), 00068 m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) 00069 { 00070 (void)body0; 00071 (void)body1; 00072 } 00073 00074 00075 00076 00077 btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm() 00078 { 00079 if (m_ownManifold) 00080 { 00081 if (m_manifoldPtr) 00082 m_dispatcher->releaseManifold(m_manifoldPtr); 00083 } 00084 } 00085 00086 void btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel) 00087 { 00088 m_lowLevelOfDetail = useLowLevel; 00089 } 00090 00091 00092 00093 extern btScalar gContactBreakingThreshold; 00094 00095 00096 // 00097 // Convex-Convex collision algorithm 00098 // 00099 void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 00100 { 00101 00102 if (!m_manifoldPtr) 00103 { 00104 //swapped? 00105 m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); 00106 m_ownManifold = true; 00107 } 00108 resultOut->setPersistentManifold(m_manifoldPtr); 00109 00110 //comment-out next line to test multi-contact generation 00111 //resultOut->getPersistentManifold()->clearManifold(); 00112 00113 00114 btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape()); 00115 btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape()); 00116 00117 btVector3 normalOnB; 00118 btVector3 pointOnBWorld; 00119 00120 { 00121 00122 00123 btGjkPairDetector::ClosestPointInput input; 00124 00125 btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver); 00126 //TODO: if (dispatchInfo.m_useContinuous) 00127 gjkPairDetector.setMinkowskiA(min0); 00128 gjkPairDetector.setMinkowskiB(min1); 00129 00130 { 00131 input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); 00132 input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; 00133 } 00134 00135 input.m_stackAlloc = dispatchInfo.m_stackAllocator; 00136 input.m_transformA = body0->getWorldTransform(); 00137 input.m_transformB = body1->getWorldTransform(); 00138 00139 gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); 00140 00141 btVector3 v0,v1; 00142 btVector3 sepNormalWorldSpace; 00143 00144 } 00145 00146 if (m_ownManifold) 00147 { 00148 resultOut->refreshContactPoints(); 00149 } 00150 00151 } 00152 00153 00154 00155 00156 btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 00157 { 00158 (void)resultOut; 00159 (void)dispatchInfo; 00161 00164 btScalar resultFraction = btScalar(1.); 00165 00166 00167 btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); 00168 btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); 00169 00170 if (squareMot0 < col0->getCcdSquareMotionThreshold() && 00171 squareMot1 < col1->getCcdSquareMotionThreshold()) 00172 return resultFraction; 00173 00174 00175 //An adhoc way of testing the Continuous Collision Detection algorithms 00176 //One object is approximated as a sphere, to simplify things 00177 //Starting in penetration should report no time of impact 00178 //For proper CCD, better accuracy and handling of 'allowed' penetration should be added 00179 //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) 00180 00181 00183 { 00184 btConvexShape* convex0 = static_cast<btConvexShape*>(col0->getCollisionShape()); 00185 00186 btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation 00187 btConvexCast::CastResult result; 00188 btVoronoiSimplexSolver voronoiSimplex; 00189 //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); 00191 btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); 00192 //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); 00193 if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), 00194 col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) 00195 { 00196 00197 //store result.m_fraction in both bodies 00198 00199 if (col0->getHitFraction()> result.m_fraction) 00200 col0->setHitFraction( result.m_fraction ); 00201 00202 if (col1->getHitFraction() > result.m_fraction) 00203 col1->setHitFraction( result.m_fraction); 00204 00205 if (resultFraction > result.m_fraction) 00206 resultFraction = result.m_fraction; 00207 00208 } 00209 00210 00211 00212 00213 } 00214 00216 { 00217 btConvexShape* convex1 = static_cast<btConvexShape*>(col1->getCollisionShape()); 00218 00219 btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation 00220 btConvexCast::CastResult result; 00221 btVoronoiSimplexSolver voronoiSimplex; 00222 //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); 00224 btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); 00225 //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); 00226 if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), 00227 col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) 00228 { 00229 00230 //store result.m_fraction in both bodies 00231 00232 if (col0->getHitFraction() > result.m_fraction) 00233 col0->setHitFraction( result.m_fraction); 00234 00235 if (col1->getHitFraction() > result.m_fraction) 00236 col1->setHitFraction( result.m_fraction); 00237 00238 if (resultFraction > result.m_fraction) 00239 resultFraction = result.m_fraction; 00240 00241 } 00242 } 00243 00244 return resultFraction; 00245 00246 } 00247