Remove Scene Node from SceneGraph

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
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Remove Scene Node from SceneGraph

Post by weloveyouclark22 »

Hello all. I am experiencing that when I attempt to remove a sceneNode from the scenegraph, I am unable to do so.
This is the part of my game loop that is supposed to execute this code.

Code: Select all

while(device->run())
        if (device->isWindowActive())
        {

            rcv.endEventProcess();
            smgr->addToDeletionQueue(beam);
            ray.start = camera->getPosition();
            if(camera->getPosition() == ninja->getPosition())
            {
                ninja->setFrameLoop(166,173);
            }
            //beam->setRotation(core::vector3df(0,0,0));
             if(rcv.leftMouseReleased())
            {
                gun->setFrameLoop(40,41);
                smgr->addToDeletionQueue(beam);
            }
            if(rcv.leftMouseDown())
            {
                gun->setFrameLoop(15, 25);
                scene::CBeamNode* beam = new scene::CBeamNode
                (q3node, smgr, -1,"media/red.jpg","media/red.jpg");
                beam->setLine(ray.start, ray.end, 7.0f);
                beam->addAnimator(ba);
                //sound->play2D("media/impact.wav", false);
            }
As you may see, I told the sceneManager to add to deletion queue in two instances (removed once instance, compiled, removed the other, same effect, left both to show where I put them). I assume that it may have something to do with my event receiver, but in that case where should I have it removed? I want the beam to be either moved as you hold down the left mouse key and removed when you lift it up, or create a new beam and remove the old beam constantly.
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

Adds a scene node to the deletion queue.

The scene node is immediatly deleted when it's secure. Which means when the scene node does not execute animators and things like that. This method is for example used for deleting scene nodes by their scene node animators. In most other cases, a ISceneNode::remove() call is enough, using this deletion queue is not necessary.
are you sure the beamnode is not executing anything?

did you tried:

Code: Select all

beam->setVisible(false);
beam->remove();
because:

Code: Select all

void CBeamSceneNode::OnRegisterSceneNode(void)
        {
            if (IsVisible)
            {
                SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT);
                ISceneNode::OnRegisterSceneNode();
            }
        }
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

no random thats not needed. the register call has to be done every frame. the problem here is probably that he adds hundreds beams and only removes one of them.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

ah ok, thx good to know beacause i also use your CBeamNode, i set them to not visible and leav them in the backgraund i thought thats less expensive than creating and removing them.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

Well yeah that probably is true when you remove and create hundreds in a short period of time. but if you do that you should take a look at my Particle engine. it has a line particle drawer implemented which works just like the beam node except its way faster for alot of nodes/particles in that case. for example for bullets from a maschinegun i would definetly say use the my particle engine.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

sounds interesting i will definitely have a look at it because i might also want to use different types of weapon in a subsequent development phase.
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Post by Radikalizm »

In general it's always a pretty bad idea to allow for uncontrolled scene node creation within your rendering/game loop

Also, an event receiver will not just catch 1 event whenever a key is pressed or a mouse button is clicked, but it will receive one for every frame the keyboard/mouse button is down
In this case it'd mean that if you'd run at 60fps and you hold down your mouse button a bit too long you could easily end up with over 60 nodes...
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Thanks for the recommendations, but this happens even when I only create one Beam Node. When I put the

Code: Select all

smgr->addToDeletionQueue(beam);
before the scene ends, it deletes them, but I am unable to see the beams before they are deleted.

Also,

Code: Select all

 beam->drop();
and

Code: Select all

beam->remove();
show no results.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

weloveyouclark22 wrote:Thanks for the recommendations, but this happens even when I only create one Beam Node. When I put the

Code: Select all

smgr->addToDeletionQueue(beam);
before the scene ends, it deletes them, but I am unable to see the beams before they are deleted.

Also,

Code: Select all

 beam->drop();
and

Code: Select all

beam->remove();
show no results.
It is impossible that they show no effect!
lets create a test case to see if you screwed up.
Create a BeamSceneNode before the mainloop and then call remove on it when you press a button. after calling remove set the pointer to 0 and never call remove again after that. now the scenenode is gone.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Hm, well it appears that my method of creating and destroying beams is extremely inefficient. Any recommendations as to how I should do it?
Mikhail9
Posts: 54
Joined: Mon Jun 29, 2009 8:41 am

Post by Mikhail9 »

I am confused by the code you first posted, and maybe you've rewritten some since then.

But your code creates the Beam Node this way:

Code: Select all

scene::CBeamNode* beam = new scene::CBeamNode 
inside of an if-then block.

That means that the variable beam goes out of scope at the end of the block and is no longer valid. The beam will still be on the screen because the scene manager has a pointer to it.

Later, in a different scope, you try to remove the beam via:

Code: Select all

smgr->addToDeletionQueue(beam)
Now, you must have a beam variable in an enclosing scope, or this wouldn't even have compiled. But the important point is that this doesn't point to the beam you created, and it probably doesn't point to anything at all, hence you get a crash when the scene manager tries to delete it, or at the very least the beam you created doesn't disappear.

You have to keep track of every beam you create (say, in a vector declared outside of the draw loop), and then delete the beams later using those pointers.
Post Reply