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!
Really basic Irrlicht help
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...
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);
}
Last edited by vitek on Mon May 22, 2006 7:05 am, edited 2 times in total.
Hi, I'm working with toc ont his project, and have tried to use your funtion like this:
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
Code: Select all
ISceneCollisionManager_getSceneNodeFromPoint(smgr, camera->getPosition(), 0)->remove();
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();
// ...