I recently posted this question, but it wasn't getting any attention so I thought I'd post it again, re-phrased.
I have two static mesh nodes that I am rendering in Irrlicht (from .3ds files). All I want to do is perform a simple "performDiscreteCollisionDetection" on these meshes. My question is:
How do I load the meshes into Bullet to perform the low level (no dynamics!) collision detection on the "btBvhTriangleMeshShape" objects? A simple example would be really useful.
Thanks in advance.
Loading a Trimesh
-
- Posts: 8
- Joined: Mon May 21, 2012 7:44 am
Re: Loading a Trimesh
I've managed to sort this out - I'm not loading the TriMesh successfully into bullet by getting the Mesh Buffer from Irrlicht and using this to pass the vertex information to Bullet in order to create my btBvhTriangleMeshShape
Now my problem is performing the collision detection. I have filled my collision world with my collision objects:
next I want to do my collision detection so I do:
Before I try anything too elaborate, all I want to do is get a bool to answer: has there been a collision? I'm not interested in the actual points to start with, just if there has been a collision or not. How do I do this?
Now my problem is performing the collision detection. I have filled my collision world with my collision objects:
Code: Select all
objects[0].setCollisionShape(triMeshShapeCube); //object1;
objects[1].setCollisionShape(triMeshShapeSphere); //object2;
pColWold = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
Code: Select all
pColWold->performDiscreteCollisionDetection();
-
- Posts: 8
- Joined: Mon May 21, 2012 7:44 am
Re: Loading a Trimesh
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:
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: Select all
#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;
};
-
- Posts: 225
- Joined: Wed Jan 07, 2009 11:43 am
- Location: London
Re: Loading a Trimesh
Might be missing it , but where are you adding your collision objects to the collision world?, hmm or even doing a stepSimulation?