Page 1 of 1

Really basic Irrlicht help

Posted: Mon May 22, 2006 3:43 am
by toc
Hi,
(Apologies in advance, I know this is going to be a very n00b post - I've just started with Irrlicht yesterday, and am trying to get my head around some parts). I've been through most of the tutorials supplied, but am trying to figure out how I'd do the following:

Basically, I want to make a simple collect-the-items game, very basic, nothing too complicated. The parts I'm haivng trouble with are:

1) How can I delete scene nodes, or make them invisible so that it appears like I have collected them? (for example, in Tutorial 7, if I wandered up to the faeries, I'd like to make them 'dissapear')

2) Is there an easy way to detect whether the camera's current position is colliding with a scene node? I'm sure there must be, but I had trouble figuring this out, since the examples within Tutorial 7 are checking for collisions with where the camera is looking, rather than from where it is positioned. Would getSceneNodeFromScreenCoordinatesBB() or getSceneNodeFrom3DPosition() help with this?

At the moment, I'm just playing around with Tutorial 7's code, treating the faeries as if they are items to be collected.

Again, sorry if this is too basic for even this forum. Any help would be greatly appreciated, or just a pointer in the right direction...

Thanks!

Posted: Mon May 22, 2006 6:45 am
by vitek
No, you are posting the questions in the right place. This is the beginners forum after all...

1. You can remove scene nodes by calling SceneNode->remove(). It may not result in the scene node being deleted immediately, but it will remove it from the scene graph, so it won't be rendered automatically. If you want to delay the removal of a scene node for a period of time, you can use the createDeleteAnimator() method of the scene manager to get an animator that will do the removal for you at a later time.

2. For efficiency reasons you may not want to do actual collision testing until you have done some sort of broad-phase checks first. You can do bounding box or bounding sphere testing fairly cheaply. At the risk of helping you out to much, I'm going to paste some code...

Code: Select all

// check to see if a point [in world coords] is inside a scene nodes box
// this is useful if you have a list of scene nodes that you want to check for intersection with
bool ISceneNode_isPointInBoundingBox(ISceneNode* node, const core::vector3df& point)
{
  return node->getTransformedBoundingBox().isPointInside(point);
}

// helper function to recursively search a scene node and all of its children
// scene nodes. will return the first scene node whose bounding box contains the provided point.
ISceneNode* ISceneCollisionManager_getSceneNodeFromPoint(ISceneNode* root, const core::vector3df& point, s32 idBitMask=0)
{
  const core::list<ISceneNode*>& children = root->getChildren();

  core::list<ISceneNode*>::Iterator it;
  for (it = children.begin(); it != children.end(); ++it)
  {
    ISceneNode* child = *it;

    if (child->isVisible() && (idBitMask == 0 || (child->getID() & isBitMask)))
    {
      if (ISceneNode_isPointInBoundingBox(child, point))
        return child;
    }
  }

  // recurse
  for (it = children.begin(); it != children.end(); ++it)
  {
    ISceneNode* match = ISceneCollisionManager_getSceneNodeFromPoint(*it, point, idBitMask);
    if (match)
      return match;
  }  

  return 0;
}

// find the first bounding box in the entire scene graph that contains the given point
ISceneNode* ISceneCollisionManager_getSceneNodeFromPoint(ISceneManager* scene, const core::vector3df& point, s32 idBitMask=0)
{
  return ISceneCollisionManager_getSceneNodeFromPoint(scene->getRootSceneNode(), point, idBitMask);
}

Posted: Mon May 22, 2006 6:53 am
by Xharock
node->setVisible(false)

That will hide your node.

Posted: Mon May 22, 2006 8:56 am
by DriftRS
Hi, I'm working with toc ont his project, and have tried to use your funtion like this:

Code: Select all

ISceneCollisionManager_getSceneNodeFromPoint(smgr, camera->getPosition(), 0)->remove();
It compiles and runs, but when I collide with the object nothing occurs... I'm probably using it wrongly, this being the first time I've used irrlicht and all, any help appreciated :)

Posted: Mon May 22, 2006 10:07 am
by vitek
I just blurted out that code and didn't really test it. I just verified that it does work, but there is a caveat. If the position you provide is that of the camera, you must prevent the camera scene node from being removed. Here is my code...

Code: Select all

   // add a camera to the scene. note that cameras get special id 0
   ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
   camera->setID(0);

   // load an animated model
   IAnimatedMesh* mesh = smgr->getMesh("media/faerie.md2");
   if (mesh)
   {
      // load a mesh scene node, this node id mask is set to 1
      IAnimatedMeshSceneNode* model = smgr->addAnimatedMeshSceneNode(mesh, 0, 1, core::vector3df(0, -20, 100));
      model->setMaterialFlag(video::EMF_LIGHTING, false);
      model->setMaterialTexture(0, driver->getTexture("media/faerie2.bmp"));
   }

   while(device->run() && driver)
   {
      // find first node with mask bit 1 set and remove it
      ISceneNode* node = ISceneCollisionManager_getSceneNodeFromPoint(smgr, smgr->getActiveCamera()->getAbsolutePosition(), 1);
      if (node)
         node->remove();
   // ...

Posted: Tue May 23, 2006 11:32 am
by toc
Cool, thanks for that! Seems to be working (for the time being at least :P)