Perform several rotation pertubations, to create multiple collision contact. works for convex versus plane. todo: convex versus convex.

See issue http://code.google.com/p/bullet/issues/detail?id=20:

Note that the default number of pertubation iterations (10) and pertubation angle (0.05) can be modified through the collisionConfiguration:

	btConvexPlaneCollisionAlgorithm::CreateFunc* func = (btConvexPlaneCollisionAlgorithm::CreateFunc*)collisionConfiguration->getCollisionAlgorithmCreateFunc(BOX_SHAPE_PROXYTYPE,STATIC_PLANE_PROXYTYPE);
	func->m_numPertubationIterations = 0;
	func = (btConvexPlaneCollisionAlgorithm::CreateFunc*)collisionConfiguration->getCollisionAlgorithmCreateFunc(STATIC_PLANE_PROXYTYPE,BOX_SHAPE_PROXYTYPE);
	func->m_numPertubationIterations = 0;
This commit is contained in:
erwin.coumans
2009-02-02 21:11:19 +00:00
parent dc5cc018f1
commit bcbe730471
2 changed files with 76 additions and 27 deletions

View File

@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty. 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. 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, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: 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. 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.
@@ -22,15 +22,17 @@ subject to the following restrictions:
//#include <stdio.h> //#include <stdio.h>
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPertubationIterations,btScalar pertubeAngle)
: btCollisionAlgorithm(ci), : btCollisionAlgorithm(ci),
m_ownManifold(false), m_ownManifold(false),
m_manifoldPtr(mf), m_manifoldPtr(mf),
m_isSwapped(isSwapped) m_isSwapped(isSwapped),
m_numPertubationIterations(numPertubationIterations),
m_pertubeAngle(pertubeAngle)
{ {
btCollisionObject* convexObj = m_isSwapped? col1 : col0; btCollisionObject* convexObj = m_isSwapped? col1 : col0;
btCollisionObject* planeObj = m_isSwapped? col0 : col1; btCollisionObject* planeObj = m_isSwapped? col0 : col1;
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj)) if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
{ {
m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj); m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
@@ -48,30 +50,28 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
} }
} }
void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& pertubeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
(void)dispatchInfo; btCollisionObject* convexObj = m_isSwapped? body1 : body0;
(void)resultOut;
if (!m_manifoldPtr)
return;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1; btCollisionObject* planeObj = m_isSwapped? body0: body1;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape(); btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape(); btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
bool hasCollision = false; bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal(); const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant(); const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform planeInConvex;
planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform(); btTransform convexWorldTransform = convexObj->getWorldTransform();
btTransform convexInPlaneTrans; btTransform convexInPlaneTrans;
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform(); convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
//now pertube the convex-world transform
convexWorldTransform.getBasis()*=btMatrix3x3(pertubeRot);
btTransform planeInConvex;
planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx); btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
@@ -87,6 +87,42 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
btVector3 pOnB = vtxInPlaneWorld; btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
} }
}
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
if (!m_manifoldPtr)
return;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btVector3 v0,v1;
btPlaneSpace1(planeNormal,v0,v1);
//first perform a collision query with the non-pertubated collision objects
{
btQuaternion rotq(0,0,0,1);
collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
}
//now perform 'm_numPertubationIterations' collision queries with the pertubated collision objects
btQuaternion pertubeRot(v0,m_pertubeAngle);
for (int i=0;i<m_numPertubationIterations;i++)
{
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPertubationIterations));
btQuaternion rotq(planeNormal,iterationAngle);
collideSingleContact(rotq.inverse()*pertubeRot*rotq,body0,body1,dispatchInfo,resultOut);
}
if (m_ownManifold) if (m_ownManifold)
{ {
if (m_manifoldPtr->getNumContacts()) if (m_manifoldPtr->getNumContacts())

View File

@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty. 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. 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, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: 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. 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.
@@ -28,18 +28,22 @@ class btPersistentManifold;
/// Other features are frame-coherency (persistent data) and collision response. /// Other features are frame-coherency (persistent data) and collision response.
class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
{ {
bool m_ownManifold; bool m_ownManifold;
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
bool m_isSwapped; bool m_isSwapped;
int m_numPertubationIterations;
btScalar m_pertubeAngle;
public: public:
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped); btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPertubationIterations, btScalar pertubeAngle);
virtual ~btConvexPlaneCollisionAlgorithm(); virtual ~btConvexPlaneCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void collideSingleContact (const btQuaternion& pertubeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(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) virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
@@ -52,15 +56,24 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
int m_numPertubationIterations;
btScalar m_pertubeAngle;
CreateFunc()
: m_numPertubationIterations(10),
m_pertubeAngle(0.05f)
{
}
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm)); void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
if (!m_swapped) if (!m_swapped)
{ {
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false); return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPertubationIterations,m_pertubeAngle);
} else } else
{ {
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true); return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPertubationIterations,m_pertubeAngle);
} }
} }
}; };