Get normal vector between a btRigidBody and kinematic charac

Pacha
Posts: 26
Joined: Sat Jun 15, 2013 2:29 am

Get normal vector between a btRigidBody and kinematic charac

Post by Pacha »

I have a kinematic character with a ghost object (the player), and I have a map full of static (mass 0) btRigidBodies. What I am trying to implement is a wall jump, so when a character is next to a btRigidBody and is on air, and if he presses the jump button, I should get the normal of that btRigidBody at the point my character is touching, so I get the direction of the jump.

I could implement it (more or less) using btManifoldPoint, but I think this only takes into consideration the broadphase, and all the normals it returns are based on cubes (so they only point in one axis (x y or z). When I rotated a btRigidBody with a btBoxShape 45 degrees, my program broke and wasn't detecting anything in that cube, only if I go to the edges, and it returns an incorrect normal.

Here is a screenshot of my game: http://i.imgur.com/3iT2EPJ.png (the blue tower and the grey platform are rotated, the rest isn't).

So far I did this (modified this from recoverFromPenetration of btKinematicCharacterController):

Code: Select all

btAlignedObjectArray<btVector3> Player::getObjectTouchingNormal()
{
	btDiscreteDynamicsWorld* world = Physics::getSingleton()->getWorld();
	mNormals->clear(); // mNormals is btAlignedObjectArray<btVector3>*
	btVector3 minAabb, maxAabb;
	mGhostObject->getCollisionShape()->getAabb(mGhostObject->getWorldTransform(), minAabb,maxAabb);
	world->getBroadphase()->setAabb(mGhostObject->getBroadphaseHandle(), 
							minAabb, 
							maxAabb, 
							world->getDispatcher());
						 
	bool penetration = false;

	world->getDispatcher()->dispatchAllCollisionPairs(mGhostObject->getOverlappingPairCache(), world->getDispatchInfo(), world->getDispatcher());
	btScalar maxPen = btScalar(0.0);
	mNumberOverlappingPairsLastUpdate = mGhostObject->getOverlappingPairCache()->getNumOverlappingPairs();
	for (int i = 0; i < mNumberOverlappingPairsLastUpdate; i++)
	{
		btManifoldArray m_manifoldArray = btManifoldArray();
		m_manifoldArray.resize(0);

		btBroadphasePair* collisionPair = &mGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
		
		if (collisionPair->m_algorithm)
			collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
		
		for (int j=0;j<m_manifoldArray.size();j++)
		{
			btPersistentManifold* manifold = m_manifoldArray[j];
			btScalar directionSign = manifold->getBody0() == mGhostObject ? btScalar(-1.0) : btScalar(1.0);
			for (int p=0;p<manifold->getNumContacts();p++)
			{
				stringstream ss;
				ss << "textbox-";
				ss << p + 2;
				const btManifoldPoint&pt = manifold->getContactPoint(p);
				mNormals->push_back(pt.m_normalWorldOnB);
			}
		}
	}
	return *mNormals;
}