So I'm having troubles with the use of Ghost Objects, and I was hoping that you could help me with that tricky thing.
I tried the versions 2.82 and 2.83.6 of bullet Physics.
I am also using a computer with Linux 14.04 LTS 64 bit. 8GB of ram, Graphic Card: Quadro FX 3500, processor: Intel Core 2 CPU 6700 with 2*2.66GHz.
I am instantiating my world that way :
Code: Select all
m_pcollisionConfig=new btDefaultCollisionConfiguration();
m_pdispatcher=new btCollisionDispatcher(m_pcollisionConfig);
m_pbroadphase=new btDbvtBroadphase();
//btVector3 worldAabbMin(-1000,-1000,-1000);
//btVector3 worldAabbMax(1000,1000,1000);
//m_pbroadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax);
m_psolver=new btSequentialImpulseConstraintSolver();
m_pworldID=new btDiscreteDynamicsWorld(m_pdispatcher,m_pbroadphase,m_psolver,m_pcollisionConfig);
m_pworldID->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
m_pworldID->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
m_pworldID->setInternalTickCallback(ghostSpherePreTickCallback,this,true);
m_pworldID->setGravity(btVector3(0.0f,0.0f,0.0f));
Code: Select all
#define BIT(x) (1<<(x))
enum collisiontypes {
COL_NOTHING = 0, //<Collide with nothing
COL_RIGIDBODY = BIT(0), //<Collide with rigidBodies
COL_GHOSTOBJECT = BIT(1), //<Collide with ghostObject
COL_TEST = BIT(2),
COL_GROUND = BIT(3),
COL_WALL = BIT(4),
COL_STATIC = BIT(5),
};
int rigidBodyCollidesWith = COL_RIGIDBODY | COL_GROUND | COL_WALL | COL_STATIC;
//int rigidBodyCollidesWith = COL_NOTHING;
int ghostObjectCollidesWith = COL_RIGIDBODY;
int staticObjectCollidesWith = COL_RIGIDBODY;
int groundCollidesWith = COL_RIGIDBODY;
I am using two objects, one is a simple rigid body, instantiated that way :
Code: Select all
/* movable sphere */
float mass = 1.0f;
float pos[7] = { 0.3f, 0.2f, 0.3f, 0.0f, 0.0f, 0.0f, 1.0f };
btTransform t;
t.setIdentity();
t.setOrigin(btVector3(0.0f,0.0f,0.0f));
btSphereShape* sphere=new btSphereShape(btScalar(radius));
//sphere->setMargin(btScalar(radius+0.005));
btVector3 inertia(0,0,0);
btMotionState* motion=new btDefaultMotionState(t);
btRigidBody::btRigidBodyConstructionInfo info(0.0f,motion,sphere,inertia);
m_prigidBodyID=new btRigidBody(info);
btVector3 inertia(0,0,0);
if(mass!=0.0f)
m_prigidBodyID->getCollisionShape()->calculateLocalInertia(btScalar(mass),inertia);
m_prigidBodyID->setMassProps(m_mass, inertia);
t.setIdentity();
btQuaternion q;
q.setX(pos[3]);
q.setY(pos[4]);
q.setZ(pos[5]);
q.setW(pos[6]);
t.setOrigin(btVector3(pos[0],pos[1],pos[2]));
t.setRotation(q);
m_prigidBodyID->setCenterOfMassTransform(t);
m_prigidBodyID->setActivationState(DISABLE_DEACTIVATION);
m_prigidBodyID->setFriction(btScalar(0.f));
m_prigidBodyID->setRestitution(btScalar(0.f));
m_pworldID->addRigidBody(m_prigidBodyID, COL_RIGIDBODY, rigidBodyCollidesWith | COL_GHOSTOBJECT);
Code: Select all
rad = 0.3f;
float pos[7] = { 0.0f, -1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f };
m_pghostObject = new btPairCachingGhostObject();
m_pghostObject->setCollisionShape(new btSphereShape(btScalar(rad)));
m_pghostObject->setCollisionFlags(m_pghostObject->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
btTransform t;
t.setIdentity();
t.setOrigin(btVector3(pos[0],pos[1],pos[2]));
m_pghostObject->setWorldTransform(t);
m_pworldID->addCollisionObject(m_pghostObject, COL_GHOSTOBJECT, ghostObjectCollidesWith);
Code: Select all
void ghostSpherePreTickCallback (btDynamicsWorld *world, btScalar timeStep)
{
btPairCachingGhostObject* ghostObject = m_pghostObject;
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray = ghostObject->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
for (int i = 0; i < numPairs; ++i)
{
manifoldArray.clear();
const btBroadphasePair& pair = pairArray[i];
btBroadphasePair* collisionPair = m_pworld_ID->getPairCache()->findPair( pair.m_pProxy0,pair.m_pProxy1);
if (!collisionPair) continue;
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
for (int j=0;j<manifoldArray.size();j++)
{
btPersistentManifold* manifold = manifoldArray[j];
bool isFirstBody = manifold->getBody0() == ghostObject;
btScalar direction = isFirstBody ? btScalar(-1.0) : btScalar(1.0);
for (int p = 0; p < manifold->getNumContacts(); ++p)
{
const btManifoldPoint&pt = manifold->getContactPoint(p);
if (pt.getDistance() < 0.f)
{
const btVector3& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB;
/*applying some manually defined forces here ...*/
}
}
}
}
}
Code: Select all
m_pworldID->stepSimulation(0.003, 10, 0.0003);
So my problem is that penetration between the movable sphere and the ghost object works perfectly well when I use a sphere shape for my ghost object, but if I tried other shapes like a box shape or a cylinder shape, firstly the penetration seems OK but everytime I penetrate with more than the half of my movable sphere there is an error raised with a Seg Fault probably coming from the solver or the stepSimulation. So I was hoping that you could help me to know where I am doing wrong.
Thanks in advance for your help,
Cheers,
NyuuDorian