Troubles using cylinder and box shapes for ghostObjects

NyuuDorian
Posts: 3
Joined: Tue Aug 18, 2015 7:23 am

Troubles using cylinder and box shapes for ghostObjects

Post by NyuuDorian »

Hi dear all !

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));
I do also define masks :

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);
And then I instantiate my ghost object that way :

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);
My callback function :

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 ...*/					
		            }
		        }
		    }
		}
	}
And finally my StepSimulation

Code: Select all

m_pworldID->stepSimulation(0.003, 10, 0.0003);
I have to add that the movable sphere is moved with a haptic device which applies forces on it (translation and rotation).
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
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Troubles using cylinder and box shapes for ghostObjects

Post by xexuxjy »

Are you running in debug mode, and if so do you have a stack trace for the segfault?
NyuuDorian
Posts: 3
Joined: Tue Aug 18, 2015 7:23 am

Re: Troubles using cylinder and box shapes for ghostObjects

Post by NyuuDorian »

Thank you for your reply !

Yes I am working with Debug Mode, I'll put 2 pictures of the Stack trace and Debugger Information (I have blacklined some personnal informations that are not important for solving the problem here, they are just some paths). I am using CodeBlocks with the GNU Debugger.
debug_info.png
debug_stack.png
You do not have the required permissions to view the files attached to this post.
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Troubles using cylinder and box shapes for ghostObjects

Post by xexuxjy »

I've had a look through the btGjkEpaSolver2::Penetration and there's very little (anything?) in the function itself that I can see that would cause an access violation, the shape0 and shape1 objects are really the only pointers provided and I don't see why they would get corrupted when it reaches a penetration point of more then half. The only thing in any of that code that would rely on the collision shapes would be the support function within them , but if that was causing the seg fault i'd of hoped to see that in the stack trace rather than the btGjkEpaSolver2::Penetration function itself. When you get the error do the shape0 and shape1 pointers still look valid?
NyuuDorian
Posts: 3
Joined: Tue Aug 18, 2015 7:23 am

Re: Troubles using cylinder and box shapes for ghostObjects

Post by NyuuDorian »

Yeah, actually I do not understand either. The only call I do is myBulletWorld->stepSimulation(...) and then it simulates the physics and call the btGJK by itself. So since my pointer to the bullet world is valid and I do not delete anything, everything else should be valid, even the shapes. I checked the pointer to the shapes and they seem okay too.
What's weird here is that it works perfectly fine when I use a sphere shape for the ghostObject but not for the others one.

I'll try to see if I can reproduce this bug ( if indeed it is one ) when not using a haptic device.
Anyway, still thank you for trying to help me with this problem,
Cheers,
NyuuDorian