Introduce kF_UseGjkConvexCastRaytest, and make kF_UseSubSimplexConvexCastRaytest the default for btCollisionWorld::rayTest See https://github.com/bulletphysics/bullet3/issues/34

Add btCollisionObject::setIgnoreCollisionCheck to disable collisions between specific instances, without having a btTypedConstraint. See https://github.com/bulletphysics/bullet3/issues/165

Make btMultiBody and btMultiBodyJointMotor backwards compatible with Bullet 2.82 API (single-DOF API)
This commit is contained in:
Erwin Coumans
2014-05-01 13:51:56 -07:00
parent 907ac49892
commit 7151865c16
10 changed files with 87 additions and 49 deletions

View File

@@ -394,23 +394,16 @@ btMultiBody* FeatherstoneMultiBodyDemo::createFeatherstoneMultiBody(class btMult
if (1) if (1)
{ {
btCollisionShape* box = new btBoxShape(btVector3(halfExtents[0],halfExtents[1],halfExtents[2])*scaling); btCollisionShape* box = new btBoxShape(btVector3(halfExtents[0],halfExtents[1],halfExtents[2])*scaling);
btRigidBody* body = new btRigidBody(mass,0,box,inertia);
btMultiBodyLinkCollider* col= new btMultiBodyLinkCollider(bod,-1); btMultiBodyLinkCollider* col= new btMultiBodyLinkCollider(bod,-1);
body->setCollisionShape(box);
col->setCollisionShape(box); col->setCollisionShape(box);
btTransform tr; btTransform tr;
tr.setIdentity(); tr.setIdentity();
tr.setOrigin(local_origin[0]); tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3])); tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3]));
body->setWorldTransform(tr);
col->setWorldTransform(tr); col->setWorldTransform(tr);
world->addCollisionObject(col, 2,1+2); world->addCollisionObject(col, 2,1+2);
col->setFriction(friction); col->setFriction(friction);
bod->setBaseCollider(col); bod->setBaseCollider(col);
} }
} }

View File

@@ -189,7 +189,7 @@ bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const
if ((!body0->isActive()) && (!body1->isActive())) if ((!body0->isActive()) && (!body1->isActive()))
needsCollision = false; needsCollision = false;
else if (!body0->checkCollideWith(body1)) else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
needsCollision = false; needsCollision = false;
return needsCollision ; return needsCollision ;

View File

@@ -110,13 +110,11 @@ protected:
/// If some object should have elaborate collision filtering by sub-classes /// If some object should have elaborate collision filtering by sub-classes
int m_checkCollideWith; int m_checkCollideWith;
btAlignedObjectArray<const btCollisionObject*> m_objectsWithoutCollisionCheck;
///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation. ///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation.
int m_updateRevision; int m_updateRevision;
virtual bool checkCollideWithOverride(const btCollisionObject* /* co */) const
{
return true;
}
public: public:
@@ -225,7 +223,34 @@ public:
return m_collisionShape; return m_collisionShape;
} }
void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
{
if (ignoreCollisionCheck)
{
//We don't check for duplicates. Is it ok to leave that up to the user of this API?
//int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
//if (index == m_objectsWithoutCollisionCheck.size())
//{
m_objectsWithoutCollisionCheck.push_back(co);
//}
}
else
{
m_objectsWithoutCollisionCheck.remove(co);
}
m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
}
virtual bool checkCollideWithOverride(const btCollisionObject* co) const
{
int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
if (index < m_objectsWithoutCollisionCheck.size())
{
return false;
}
return true;
}

View File

@@ -294,10 +294,11 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
bool condition = true; bool condition = true;
btConvexCast* convexCasterPtr = 0; btConvexCast* convexCasterPtr = 0;
if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest) //use kF_UseSubSimplexConvexCastRaytest by default
convexCasterPtr = &subSimplexConvexCaster; if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest)
else
convexCasterPtr = &gjkConvexCaster; convexCasterPtr = &gjkConvexCaster;
else
convexCasterPtr = &subSimplexConvexCaster;
btConvexCast& convexCaster = *convexCasterPtr; btConvexCast& convexCaster = *convexCasterPtr;

View File

@@ -21,6 +21,7 @@ subject to the following restrictions:
struct btBroadphaseProxy; struct btBroadphaseProxy;
class btConvexShape; class btConvexShape;
class btTriangleRaycastCallback: public btTriangleCallback class btTriangleRaycastCallback: public btTriangleCallback
{ {
public: public:
@@ -32,10 +33,12 @@ public:
//@BP Mod - allow backface filtering and unflipped normals //@BP Mod - allow backface filtering and unflipped normals
enum EFlags enum EFlags
{ {
kF_None = 0, kF_None = 0,
kF_FilterBackfaces = 1 << 0, kF_FilterBackfaces = 1 << 0,
kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle
kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm ///SubSimplexConvexCastRaytest is the default, even if kF_None is set.
kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm
kF_UseGjkConvexCastRaytest = 1 << 3,
kF_Terminator = 0xFFFFFFFF kF_Terminator = 0xFFFFFFFF
}; };
unsigned int m_flags; unsigned int m_flags;

View File

@@ -317,38 +317,48 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
} }
bool btRigidBody::checkCollideWithOverride(const btCollisionObject* co) const
{
const btRigidBody* otherRb = btRigidBody::upcast(co);
if (!otherRb)
return true;
for (int i = 0; i < m_constraintRefs.size(); ++i)
{
const btTypedConstraint* c = m_constraintRefs[i];
if (c->isEnabled())
if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
return false;
}
return true;
}
void btRigidBody::addConstraintRef(btTypedConstraint* c) void btRigidBody::addConstraintRef(btTypedConstraint* c)
{ {
int index = m_constraintRefs.findLinearSearch(c); ///disable collision with the 'other' body
if (index == m_constraintRefs.size())
m_constraintRefs.push_back(c);
m_checkCollideWith = true; int index = m_constraintRefs.findLinearSearch(c);
//don't add constraints that are already referenced
btAssert(index == m_constraintRefs.size());
if (index == m_constraintRefs.size())
{
m_constraintRefs.push_back(c);
btCollisionObject* colObjA = &c->getRigidBodyA();
btCollisionObject* colObjB = &c->getRigidBodyB();
if (colObjA == this)
{
colObjA->setIgnoreCollisionCheck(colObjB, true);
}
else
{
colObjB->setIgnoreCollisionCheck(colObjA, true);
}
}
} }
void btRigidBody::removeConstraintRef(btTypedConstraint* c) void btRigidBody::removeConstraintRef(btTypedConstraint* c)
{ {
int index = m_constraintRefs.findLinearSearch(c);
//don't remove constraints that are not referenced
btAssert(index < m_constraintRefs.size());
m_constraintRefs.remove(c); m_constraintRefs.remove(c);
m_checkCollideWith = m_constraintRefs.size() > 0; btCollisionObject* colObjA = &c->getRigidBodyA();
btCollisionObject* colObjB = &c->getRigidBodyB();
if (colObjA == this)
{
colObjA->setIgnoreCollisionCheck(colObjB, false);
}
else
{
colObjB->setIgnoreCollisionCheck(colObjA, false);
}
} }
int btRigidBody::calculateSerializeBufferSize() const int btRigidBody::calculateSerializeBufferSize() const

View File

@@ -87,7 +87,7 @@ class btRigidBody : public btCollisionObject
//m_optionalMotionState allows to automatic synchronize the world transform for active objects //m_optionalMotionState allows to automatic synchronize the world transform for active objects
btMotionState* m_optionalMotionState; btMotionState* m_optionalMotionState;
//keep track of typed constraints referencing this rigid body //keep track of typed constraints referencing this rigid body, to disable collision between linked bodies
btAlignedObjectArray<btTypedConstraint*> m_constraintRefs; btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
int m_rigidbodyFlags; int m_rigidbodyFlags;
@@ -506,8 +506,6 @@ public:
return (getBroadphaseProxy() != 0); return (getBroadphaseProxy() != 0);
} }
virtual bool checkCollideWithOverride(const btCollisionObject* co) const;
void addConstraintRef(btTypedConstraint* c); void addConstraintRef(btTypedConstraint* c);
void removeConstraintRef(btTypedConstraint* c); void removeConstraintRef(btTypedConstraint* c);

View File

@@ -45,14 +45,15 @@ public:
// initialization // initialization
// //
btMultiBody(int n_links, // NOT including the base btMultiBody(int n_links, // NOT including the base
btScalar mass, // mass of base btScalar mass, // mass of base
const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal
bool fixedBase, // whether the base is fixed (true) or can move (false) bool fixedBase, // whether the base is fixed (true) or can move (false)
bool canSleep, bool canSleep,
bool multiDof bool multiDof = false
); );
~btMultiBody(); ~btMultiBody();
void setupPrismatic(int i, // 0 to num_links-1 void setupPrismatic(int i, // 0 to num_links-1

View File

@@ -21,6 +21,12 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
btMultiBodyJointMotor::btMultiBodyJointMotor(btMultiBody* body, int link, btScalar desiredVelocity, btScalar maxMotorImpulse)
:btMultiBodyJointMotor(body,link,0,desiredVelocity,maxMotorImpulse)
{
}
btMultiBodyJointMotor::btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse) btMultiBodyJointMotor::btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse)
//:btMultiBodyConstraint(body,0,link,-1,1,true), //:btMultiBodyConstraint(body,0,link,-1,1,true),
:btMultiBodyConstraint(body,body,link,link,1,true), :btMultiBodyConstraint(body,body,link,link,1,true),

View File

@@ -30,6 +30,7 @@ protected:
public: public:
btMultiBodyJointMotor(btMultiBody* body, int link,btScalar desiredVelocity, btScalar maxMotorImpulse);
btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse); btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse);
virtual ~btMultiBodyJointMotor(); virtual ~btMultiBodyJointMotor();