Loading a Trimesh

en51nm
Posts: 8
Joined: Mon May 21, 2012 7:44 am

Loading a Trimesh

Post by en51nm »

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.
en51nm
Posts: 8
Joined: Mon May 21, 2012 7:44 am

Re: Loading a Trimesh

Post by en51nm »

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 :D

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);
next I want to do my collision detection so I do:

Code: Select all

pColWold->performDiscreteCollisionDetection();
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?
en51nm
Posts: 8
Joined: Mon May 21, 2012 7:44 am

Re: Loading a Trimesh

Post by en51nm »

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:

Image

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;
};


xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: Loading a Trimesh

Post by xexuxjy »

Might be missing it , but where are you adding your collision objects to the collision world?, hmm or even doing a stepSimulation?