Shockeye:
Thanks for your comment. I know Ninja's pivot is between the two foots. My concern is that Ninja cannot collide with the the wall exactly. The video shows Ninja collides with the big bonding box ( shown by SceneNode::showBoundingBox(true)).
My code is like the following:
Collision world set-up:
Code: Select all
//Bullet initialisation.
mBroadphase = new btAxisSweep3(btVector3(-10000,-10000,-10000), btVector3(10000,10000,10000), 1024);
mCollisionConfig = new btDefaultCollisionConfiguration();
mDispatcher = new btCollisionDispatcher(mCollisionConfig);
mSolver = new btSequentialImpulseConstraintSolver();
mCollisionWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConfig);
CollisionObject class to link SceneNode and btCollisionObject:
Code: Select all
class CollisionObject : public btCollisionObject
{
public:
CollisionObject(Ogre::SceneNode *node)
{
mSceneNode = node;
this->getWorldTransform().setOrigin(BtOgre::Convert::toBullet(mSceneNode->getPosition()));
this->getWorldTransform().setRotation(BtOgre::Convert::toBullet(mSceneNode->getOrientation()));
}
virtual ~CollisionObject() {}
Ogre::SceneNode *mSceneNode;
};
Ninja set-up:
Code: Select all
//Create shape.
BtOgre::StaticMeshToShapeConverter converter(mCharacterEntity);
mCharacterShape = converter.createBox();
mCharacterShape->setLocalScaling(BtOgre::Convert::toBullet(mCharacterNode->getScale()));
// Create collision object and assign shape
mCharacterCollObject = new CollisionObject(mCharacterNode);
mCharacterCollObject->setCollisionShape(mCharacterShape);
// add character collision objec to world
mCollisionWorld->addCollisionObject(mCharacterCollObject);
Wall set-up:
Code: Select all
CollisionObject* collObj = new CollisionObject(mWallNode));
BtOgre::StaticMeshToShapeConverter aConverter(ent);
btCollisionShape *shape = aConverter.createBox();
collObj->setCollisionShape(shape);
mCollisionWorld->addCollisionObject(collObj);
Collision detection and resolution:
Code: Select all
Ogre::Vector3 curPos = mCharacterNode->getPosition();
mCharacterCollObject->getWorldTransform().setOrigin(btVector3(curPos.x, curPos.y, curPos.z));
if (mCollisionWorld)
mCollisionWorld->performDiscreteCollisionDetection();
int numManifolds = mCollisionWorld->getDispatcher()->getNumManifolds();
if (numManifolds > 0)
PRINTF("%d Collisions occurred", numManifolds);
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = mCollisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
CollisionObject* obA = static_cast<CollisionObject*>(contactManifold->getBody0());
CollisionObject* obB = static_cast<CollisionObject*>(contactManifold->getBody1());
if (obA == mCharacterCollObject || obB == mCharacterCollObject)
{
PRINTF("Collistion Hit between %s and %s\n", obA->mSceneNode->getName().c_str(), obB->mSceneNode->getName().c_str());
mCharacterNode->setPosition(prevPos);
mCharacterCollObject->getWorldTransform().setOrigin(btVector3(prevPos.x, prevPos.y, prevPos.z));
}
}