I'm going crazy trying to get this (what should be) simple code to work... here is what I have so far along with a re-cap of what I'm trying to achieve:
1. Load two simple meshes into irrlicht for rendering
2. Create my bullet world and convert the irrlicht mesh to bullet objects (mesh conversion taken from Bucky1000's simple bullet wrapper)
3. Perform collision detection and output to see if anything has collided
4. Draw result
At the moment to keep thing simple (very simple!) I'm not doing the collision detection in the draw loop, just checking if there is any collision in the default position and then drawing. The code compiles fine but doesn't say if I have a collision even thought there is (see pic). Upon closer inspection, while debugging I've notices that numManifolds=0 so the program never enters the loop to check for contacts as I don't have any manifolds (apparently!?).
Any ideas?
Collision:

Full Code:
Code:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib")
//#pragma comment(lib, "BulletCollision.lib")
//#pragma comment(lib, "LinearMath.lib")
#pragma comment(lib, "BulletCollision_debug.lib")
#pragma comment(lib, "LinearMath_debug.lib")
#endif
#include <iostream>
#include <irrlicht.h>
#include <btBulletCollisionCommon.h>
using namespace irr;
//Function protoypes
btTriangleMesh* ConvertIrrMeshToBulletTriangleMesh(scene::IMesh*,const core::vector3df&);
int main()
{
//define screen size
int width = 800;
int height = 600;
//ask user for a driver
IrrlichtDevice* pDevice = createDevice(video::EDT_DIRECT3D9,core::dimension2d<u32>(width,height),32,false,false,false,false);
//set some pointers
video::IVideoDriver* pDriver = pDevice->getVideoDriver();
scene::ISceneManager* pSmgr = pDevice->getSceneManager();
gui::IGUIEnvironment* pGUIenv = pDevice->getGUIEnvironment();
//create a sphere object
scene::IAnimatedMeshSceneNode* pSphere = pSmgr->addAnimatedMeshSceneNode(pSmgr->getMesh("Sphere.3DS"));
if(pSphere)
{
pSphere->setPosition(core::vector3df(0,0,0));
pSphere->setMaterialTexture(0, pDriver->getTexture("wood01.jpg"));
pSphere->setMaterialFlag(video::EMF_LIGHTING, false);
}
//create a simple mesh object
scene::IAnimatedMeshSceneNode* pCube = pSmgr->addAnimatedMeshSceneNode(pSmgr->getMesh("Cube.3DS"));
if(pCube)
{
pCube->setPosition(core::vector3df(0,0,0));
pCube->setMaterialTexture(0, pDriver->getTexture("aluminumbrush2030.jpg"));
pCube->setMaterialFlag(video::EMF_LIGHTING, false);
}
//init physics
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btCollisionWorld* pColWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
//Create Collision Objects
btTriangleMesh* indexVertexArrays1 = ConvertIrrMeshToBulletTriangleMesh(pSphere->getMesh(),pSphere->getScale());
btBvhTriangleMeshShape* triMeshShapeSphere = new btBvhTriangleMeshShape(indexVertexArrays1, true);
btTriangleMesh* indexVertexArrays2 = ConvertIrrMeshToBulletTriangleMesh(pCube->getMesh(),pCube->getScale());
btBvhTriangleMeshShape* triMeshShapeCube = new btBvhTriangleMeshShape(indexVertexArrays2, true);
btCollisionObject Object1;
Object1.setCollisionShape(triMeshShapeSphere);
btCollisionObject Object2;
Object1.setCollisionShape(triMeshShapeCube);
//Perform Collision Detection
pColWorld->performDiscreteCollisionDetection();
//Check all manifolds for collision
int numManifolds = pColWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = pColWorld->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
int NumContacts = contactManifold->getNumContacts();
if(NumContacts==0)
{
std::cout << "No Collision!" << std::endl;
}
else
{
std::cout << "Collision!" << std::endl;
}
}
//create a FP camera
pSmgr->addCameraSceneNodeFPS();
pDevice->getCursorControl()->setVisible(false);
//add draw loop
int lastFPS = -1;
core::vector3df LastPosition = core::vector3df(0.f,0.f,0.f);
while(pDevice->run())
{
//draw scene
pDriver->beginScene(true, true, video::SColor(255,133,133,133));
pSmgr->drawAll();
pDriver->endScene();
int fps = pDriver->getFPS();
if(lastFPS != fps)
{
core::stringw tmp(L"Collision Detection Test - Irrlicht Engine [");
tmp += pDriver->getName();
tmp += L"] fps: ";
tmp += fps;
pDevice->setWindowCaption(tmp.c_str());
lastFPS = fps;
}
}
pDevice->drop();
//delete collision objects
delete indexVertexArrays1;
delete indexVertexArrays2;
delete triMeshShapeSphere;
delete triMeshShapeCube;
return 0;
}
btTriangleMesh* ConvertIrrMeshToBulletTriangleMesh(scene::IMesh* pMesh,const core::vector3df& scaling)
{
btVector3 vertices[3];
u32 i,j,k,index,numVertices,numIndices;
u16* mb_indices;
btTriangleMesh *pTriMesh = new btTriangleMesh();
for (i=0; i<pMesh->getMeshBufferCount(); i++)
{
scene::IMeshBuffer* mb=pMesh->getMeshBuffer(i);
if(mb->getVertexType()==video::EVT_STANDARD)
{
video::S3DVertex* mb_vertices=(video::S3DVertex*)mb->getVertices();
mb_indices = mb->getIndices();
numVertices = mb->getVertexCount();
numIndices = mb->getIndexCount();
for(j=0;j<numIndices;j+=3)
{
for (k=0;k<3;k++)
{
index = mb_indices[j+k];
vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
}
pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
}
}
else if(mb->getVertexType()==video::EVT_2TCOORDS)
{
video::S3DVertex2TCoords* mb_vertices=(video::S3DVertex2TCoords*)mb->getVertices();
mb_indices = mb->getIndices();
numVertices = mb->getVertexCount();
numIndices = mb->getIndexCount();
for(j=0;j<numIndices;j+=3)
{
for (k=0;k<3;k++)
{
index = mb_indices[j+k];
vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
}
pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
}
}
}
return pTriMesh;
};