How to enable collision detection btwn the faerie and cam?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Weng
Posts: 97
Joined: Tue Oct 03, 2006 4:23 pm
Location: Singapore

How to enable collision detection btwn the faerie and cam?

Post by Weng »

I am trying to make some changes to the Collision detection and response tutorial by making the camera and the faeries have collision detection between one another. i.e the camera cannot go through the faeries

I have tried using the createCollisionResponseAnimator method:

Code: Select all

.......

node = smgr->addAnimatedMeshSceneNode(faerie);
node->setPosition(core::vector3df(-70,0,-90));
node->setMD2Animation(scene::EMAT_RUN);
node->getMaterial(0) = material;

scene::ISceneNodeAnimator *anim2 = smgr->createCollisionResponseAnimator(selector, node,
           core::vector3df(30,50,30),core::vector3df(0,-3,0),
           core::vector3df(0,20,0)); 
node->addAnimator(anim2);
anim2->drop();
..........
But the FPS Camera still manages to go through the faeries. How should I make the FPS Camera not to go through the faeries? :?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You need to create a meta selector. That meta selector has to know about the triangle selectors for everything that you want a given node to collide with. If you want the camera to collide with all faeries and the terrain, and a house, you need to create selectors for each of those things, add them to a meta selector, and use that meta selector for a collision response animator that is applied to the camera.

So first off, you need a triangle selector for every faerie. If you want to collide with terrain, you need to create a selector for the terrain.

Code: Select all

// assuming you have an array of faeries...
core::array<scene::ISceneNode*> faeries;

// give each faerie a triangle selector
for (u32 f = 0; f < faeries.size(); ++f)
{
  scene::ITriangleSelector* selector = smgr->createTriangleSelectorFromBoundingBox( faeries[f] );
    faeries[f]->setTriangleSelector( selector );
  selector->drop();
}

// give the terrain a selector
scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(terrain);
  terrain->setTriangleSelector(selector);
selector->drop();
For camera collision, you make a meta selector and add each of the faerie triangle selectors to that. Then you pass that meta selector to the collision response animator, and then add that animator to the camera.

Code: Select all

// now create a collision response animator to keep the camera from running through the faeries or the ground.

scene::IMetaTriangleSelector* meta =
    smgr->createMetaTriangleSelector();

for (u32 f = 0; f < faeries.size(); ++f)
{
   meta->addTriangleSelector( faeries[f]->getTriangleSelector() );    
}

meta->addTriangleSelector( terrain->getTriangleSelector() );

scene::ISceneNodeAnimator* anim =
    smgr->createCollisionResponseAnimator(meta, faeries[f],
          core::vector3df(30,50,30),
          core::vector3df(0,-3,0), 
          core::vector3df(0,20,0));
  camera->addAnimator(anim);
anim->drop();
If you want the faeries to not collide with each other, you build up a meta selector for each faerie. That meta selector would need to have triangle selectors for each of the other faeries and possibly the ground. You would create a collision animator for the meta selector, and add it to the faerie.

Code: Select all

// now create a collision response animator to keep each faerie from running into the others

for (u32 f = 0; f < faeries.size(); ++f)
{
  scene::IMetaTriangleSelector* meta =
    smgr->createMetaTriangleSelector();

  for (u32 g = 0; g < faeries.size(); ++g)
  {
    if (g == f)
      continue;

   meta->addTriangleSelector( faeries[g]->getTriangleSelector() );    
  }

  // you may not want or need this
  // meta->addTriangleSelector( terrain->getTriangleSelector() );

  scene::ISceneNodeAnimator* anim =
      smgr->createCollisionResponseAnimator(meta, faeries[f],
            core::vector3df(30,50,30),
            core::vector3df(0,-3,0), 
            core::vector3df(0,20,0));
    faeries[f]->addAnimator(anim);
  anim->drop();
}
If you are loading this stuff from an .irr file, I have posted some code that may help you here. I have also posted some useful code here.

Travis
Weng
Posts: 97
Joined: Tue Oct 03, 2006 4:23 pm
Location: Singapore

Post by Weng »

wow, that's very comprehensive! Thank you!~ :D
diegomazala
Posts: 14
Joined: Fri May 18, 2007 12:09 am
Contact:

I don't understand :/

Post by diegomazala »

I'm sorry, but I didn't understand.
My code doesn't works :oops:

Look:

I have 1 faerie only. So, my code:

Code: Select all

//========== Cria Camera ==================
scene::ICameraSceneNode* camera = 
		smgr->addCameraSceneNodeFPS(0, 100.0f, 300.0f, -1, 0, 0, true);
	camera->setPosition(core::vector3df(-100,20,-150));
//========== Cria Camera ==================

//========== Load Map ==================
	device->getFileSystem()->addZipFileArchive("D:/Programs/irrlicht-1.3/media/map-20kdm2.pk3");
scene::IAnimatedMesh* mapMesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* mapNode = 0;
if (mapMesh)
	mapNode = smgr->addOctTreeSceneNode(mapMesh->getMesh(0));
//========== Load Map ==================


//========== Add Faeries ==================
video::SMaterial material;
material.Textures[0] = driver->getTexture("D:/Programs/irrlicht-1.3/media/faerie2.bmp");
material.Lighting = true;
scene::IAnimatedMeshSceneNode* nodeFaerie = 0;
scene::IAnimatedMesh* faerieMesh = smgr->getMesh("D:/Programs/irrlicht-1.3/media/faerie.md2");

if (faerieMesh)
{
	nodeFaerie = smgr->addAnimatedMeshSceneNode(faerieMesh);
	nodeFaerie->setPosition(core::vector3df(-70,0,-90));
	nodeFaerie->setMD2Animation(scene::EMAT_RUN);
	nodeFaerie->getMaterial(0) = material;
}
material.Textures[0] = 0;
material.Lighting = false;
//========== Add Faeries ==================

//========== Add Triangle Selector ==================
scene::ITriangleSelector* selector = 0;

if (mapNode)
{		
	mapNode->setPosition(core::vector3df(-1350,-130,-1400));
	selector = smgr->createOctTreeTriangleSelector(mapMesh->getMesh(0), mapNode, 128);
	mapNode->setTriangleSelector(selector);
	selector->drop();
}
//========== Add Triangle Selector ==================


//========== Add Camera Collision ==================
scene::ISceneNodeAnimator* animCamera = smgr->createCollisionResponseAnimator(
		selector, camera, core::vector3df(30,50,30),
		core::vector3df(0,-3,0), 
		core::vector3df(0,50,0));
	camera->addAnimator(animCamera);
//========== Add Camera Collision ==================


animCamera->drop();





Now, the scene will be shown but the collision doesn't work.
The triangles from bounding box are drawn when the faerie is in line of collision, but no collision.
In the console, an error is repeated: 
CollisionResponseAnimator only works with same scene node as set as object during creation.

Please, can anyone help me?
Thanks
Weng
Posts: 97
Joined: Tue Oct 03, 2006 4:23 pm
Location: Singapore

Re: I don't understand :/

Post by Weng »

diegomazala wrote:I'm sorry, but I didn't understand.
My code doesn't works :oops:

I have 1 faerie only. So, my code:

Now, the scene will be shown but the collision doesn't work.
The triangles from bounding box are drawn when the faerie is in line of collision, but no collision.
In the console, an error is repeated:
CollisionResponseAnimator only works with same scene node as set as object during creation.

Please, can anyone help me?
Thanks
I have tried vitek's method with 1 faerie and it can work. Here's it. Hope it helps :)

Code: Select all

//Create a triangle selector for collision (faerie)
scene::ITriangleSelector *triangleSelector = smgr->createTriangleSelectorFromBoundingBox(node);
node->setTriangleSelector(triangleSelector);
triangleSelector->drop();

//Create a triangle selector for collision (map)
scene::ITriangleSelector *triangleSelector2 = smgr->createOctTreeTriangleSelector(q3levelmesh->getMesh(0),
							q3node,128);
q3node->setTriangleSelector(triangleSelector2);
triangleSelector2->drop();

//Use a meta triangle selector to "store" all the triangle selectors
scene::IMetaTriangleSelector *meta = smgr->createMetaTriangleSelector();
meta->addTriangleSelector(node->getTriangleSelector());
meta->addTriangleSelector(q3node->getTriangleSelector());
		
//Create an FPS camera and add a collision response animator using the meta
//triangle selector as one of the parameters. In this way, the camera can have
//collision detection with the enemy and the walls
scene::ICameraSceneNode *camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
camera->setPosition(core::vector3df(800,300,1030));
		
scene::ISceneNodeAnimator *anim = smgr->createCollisionResponseAnimator(meta,
camera,core::vector3df(30,50,30),core::vector3df(0,-2,0),core::vector3df(0,20,0)); //reduce y for the last parameter to stop the cam from rising too high
camera->addAnimator(anim);
anim->drop();
Post Reply