Page 1 of 1
Remove Scene Node from SceneGraph
Posted: Wed Mar 02, 2011 1:25 am
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.
Posted: Wed Mar 02, 2011 2:49 am
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();
}
}
Posted: Wed Mar 02, 2011 3:57 am
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.
Posted: Wed Mar 02, 2011 6:40 am
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.
Posted: Wed Mar 02, 2011 7:52 am
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.
Posted: Wed Mar 02, 2011 9:27 am
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.
Posted: Wed Mar 02, 2011 2:18 pm
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...
Posted: Wed Mar 02, 2011 4:22 pm
by weloveyouclark22
Thanks for the recommendations, but this happens even when I only create one Beam Node. When I put the
before the scene ends, it deletes them, but I am unable to see the beams before they are deleted.
Also,
and
show no results.
Posted: Wed Mar 02, 2011 6:03 pm
by sudi
weloveyouclark22 wrote:Thanks for the recommendations, but this happens even when I only create one Beam Node. When I put the
before the scene ends, it deletes them, but I am unable to see the beams before they are deleted.
Also,
and
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.
Posted: Thu Mar 03, 2011 1:17 am
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?
Posted: Thu Mar 03, 2011 3:12 am
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:
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.