+ fixed issue related to temporary/root collision shape in btCollisionObject
+ normalize plane normal input for btStaticPlaneShape + fixed issue related to swapped collision detectors (SphereTriangleDetector in particular) Thanks a lot to Andrey Tuganov for reporting the issue and his reproduction case ( http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2143 )
This commit is contained in:
@@ -26,7 +26,7 @@ m_triangle(triangle)
|
||||
|
||||
}
|
||||
|
||||
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
|
||||
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
|
||||
{
|
||||
|
||||
(void)debugDraw;
|
||||
@@ -42,7 +42,16 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
|
||||
|
||||
if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact))
|
||||
{
|
||||
output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
|
||||
if (swapResults)
|
||||
{
|
||||
btVector3 normalOnB = transformB.getBasis()*normal;
|
||||
btVector3 normalOnA = -normalOnB;
|
||||
btVector3 pointOnA = transformB*point+normalOnB*depth;
|
||||
output.addContactPoint(normalOnA,pointOnA,depth);
|
||||
} else
|
||||
{
|
||||
output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class btTriangleShape;
|
||||
/// sphere-triangle to match the btDiscreteCollisionDetectorInterface
|
||||
struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
|
||||
{
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
|
||||
|
||||
SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle);
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
|
||||
return cnum;
|
||||
}
|
||||
|
||||
void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/)
|
||||
void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/)
|
||||
{
|
||||
|
||||
const btTransform& transformA = input.m_transformA;
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
virtual ~btBoxBoxDetector() {};
|
||||
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -33,10 +33,11 @@ m_isSwapped(isSwapped)
|
||||
m_childCollisionAlgorithms.resize(numChildren);
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
btCollisionShape* tmpShape = colObj->getCollisionShape();
|
||||
btCollisionShape* childShape = compoundShape->getChildShape(i);
|
||||
colObj->internalSetTemporaryCollisionShape( childShape );
|
||||
m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj);
|
||||
colObj->setCollisionShape( colObj->getRootCollisionShape());
|
||||
colObj->internalSetTemporaryCollisionShape( tmpShape );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,18 +79,17 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
|
||||
btTransform orgTrans = colObj->getWorldTransform();
|
||||
btTransform orgInterpolationTrans = colObj->getInterpolationWorldTransform();
|
||||
|
||||
btCollisionShape* orgShape = colObj->getCollisionShape();
|
||||
|
||||
const btTransform& childTrans = compoundShape->getChildTransform(i);
|
||||
btTransform newChildWorldTrans = orgTrans*childTrans ;
|
||||
colObj->setWorldTransform( newChildWorldTrans);
|
||||
colObj->setInterpolationWorldTransform(newChildWorldTrans);
|
||||
|
||||
//the contactpoint is still projected back using the original inverted worldtrans
|
||||
colObj->setCollisionShape( childShape );
|
||||
btCollisionShape* tmpShape = colObj->getCollisionShape();
|
||||
colObj->internalSetTemporaryCollisionShape( childShape );
|
||||
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
|
||||
//revert back
|
||||
colObj->setCollisionShape( orgShape);
|
||||
colObj->internalSetTemporaryCollisionShape( tmpShape);
|
||||
colObj->setWorldTransform( orgTrans );
|
||||
colObj->setInterpolationWorldTransform(orgInterpolationTrans);
|
||||
}
|
||||
@@ -123,20 +123,20 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
|
||||
|
||||
//backup
|
||||
btTransform orgTrans = colObj->getWorldTransform();
|
||||
btCollisionShape* orgShape = colObj->getCollisionShape();
|
||||
|
||||
|
||||
const btTransform& childTrans = compoundShape->getChildTransform(i);
|
||||
//btTransform newChildWorldTrans = orgTrans*childTrans ;
|
||||
colObj->setWorldTransform( orgTrans*childTrans );
|
||||
|
||||
colObj->setCollisionShape( childShape );
|
||||
btCollisionShape* tmpShape = colObj->getCollisionShape();
|
||||
colObj->internalSetTemporaryCollisionShape( childShape );
|
||||
btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
|
||||
if (frac<hitFraction)
|
||||
{
|
||||
hitFraction = frac;
|
||||
}
|
||||
//revert back
|
||||
colObj->setCollisionShape( orgShape);
|
||||
colObj->internalSetTemporaryCollisionShape( tmpShape);
|
||||
colObj->setWorldTransform( orgTrans);
|
||||
}
|
||||
return hitFraction;
|
||||
|
||||
@@ -117,6 +117,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
|
||||
btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
|
||||
tm.setMargin(m_collisionMarginTriangle);
|
||||
|
||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||
ob->internalSetTemporaryCollisionShape( &tm );
|
||||
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
|
||||
@@ -129,7 +130,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
|
||||
colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
colAlgo->~btCollisionAlgorithm();
|
||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||
ob->setCollisionShape( ob->getRootCollisionShape());
|
||||
ob->internalSetTemporaryCollisionShape( tmpShape);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -247,6 +247,8 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg
|
||||
{
|
||||
return m_planeConvexCF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
|
||||
{
|
||||
|
||||
@@ -60,10 +60,12 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
|
||||
|
||||
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
|
||||
input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
|
||||
input.m_transformA = col0->getWorldTransform();
|
||||
input.m_transformB = col1->getWorldTransform();
|
||||
input.m_transformA = sphereObj->getWorldTransform();
|
||||
input.m_transformB = triObj->getWorldTransform();
|
||||
|
||||
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
bool swapResults = m_swapped && !m_ownManifold;
|
||||
|
||||
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults);
|
||||
|
||||
if (m_ownManifold)
|
||||
resultOut->refreshContactPoints();
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
#include "btCollisionDispatcher.h"
|
||||
|
||||
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
|
||||
class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
bool m_swapped;
|
||||
|
||||
public:
|
||||
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
|
||||
|
||||
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
#include "btCollisionDispatcher.h"
|
||||
|
||||
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
|
||||
class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
bool m_swapped;
|
||||
|
||||
public:
|
||||
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
|
||||
|
||||
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
if (m_manifoldPtr && m_ownManifold)
|
||||
{
|
||||
manifoldArray.push_back(m_manifoldPtr);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~btSphereTriangleCollisionAlgorithm();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
|
||||
|
||||
return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
|
||||
}
|
||||
|
||||
virtual ~btSphereTriangleCollisionAlgorithm();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
|
||||
|
||||
return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
|
||||
:m_planeNormal(planeNormal),
|
||||
:m_planeNormal(planeNormal.normalized()),
|
||||
m_planeConstant(planeConstant),
|
||||
m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
|
||||
{
|
||||
// btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ struct btDiscreteCollisionDetectorInterface
|
||||
// give either closest points (distance > 0) or penetration (distance)
|
||||
// the normal always points from B towards A
|
||||
//
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) = 0;
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ m_catchDegeneracies(1)
|
||||
{
|
||||
}
|
||||
|
||||
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
|
||||
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
|
||||
{
|
||||
btScalar distance=btScalar(0.);
|
||||
btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
|
||||
virtual ~btGjkPairDetector() {};
|
||||
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
|
||||
|
||||
void setMinkowskiA(btConvexShape* minkA)
|
||||
{
|
||||
|
||||
@@ -127,25 +127,19 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
||||
{
|
||||
btCollisionShape* tm = shapeCache[partId][triangleIndex];
|
||||
|
||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||
|
||||
//copy over user pointers to temporary shape
|
||||
tm->setUserPointer(tmpShape->getUserPointer());
|
||||
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
|
||||
|
||||
ob->setCollisionShape( tm );
|
||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||
ob->internalSetTemporaryCollisionShape( tm );
|
||||
|
||||
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
|
||||
///this should use the btDispatcher, so the actual registered algorithm is used
|
||||
// btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
|
||||
|
||||
//m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex);
|
||||
// cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
|
||||
// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
|
||||
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
colAlgo->~btCollisionAlgorithm();
|
||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||
ob->setCollisionShape( tmpShape );
|
||||
ob->internalSetTemporaryCollisionShape( tmpShape);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,12 +176,12 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
||||
|
||||
//btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
|
||||
// tm.setMargin(m_collisionMarginTriangle);
|
||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||
|
||||
//copy over user pointers to temporary shape
|
||||
tm->setUserPointer(tmpShape->getUserPointer());
|
||||
|
||||
ob->setCollisionShape( tm );
|
||||
//copy over user pointers to temporary shape
|
||||
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
|
||||
|
||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||
ob->internalSetTemporaryCollisionShape( tm );
|
||||
|
||||
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
|
||||
@@ -200,7 +194,7 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
||||
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
colAlgo->~btCollisionAlgorithm();
|
||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||
ob->setCollisionShape( tmpShape );
|
||||
ob->internalSetTemporaryCollisionShape( tmpShape );
|
||||
// delete tm;
|
||||
|
||||
shapeCache[partId][triangleIndex] = tm;
|
||||
|
||||
Reference in New Issue
Block a user