How do I modify an element without adding it again?

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
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

How do I modify an element without adding it again?

Post by Devil Master »

I'm working on a game where you can walk around on foot or board a spaceship and fly around. At the same time, rescalable GUI elements display information about the environment.
At the moment, I obtain this effect by adding the same element again and again whenever it needs to change. For example, when I board a spaceship (so that the camera must switch from one that moves in the horizontal plane only, to one that allows full 3D movement) I do this:

Code: Select all

camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.025f,-1,keyMap,0,false,0.f);
Conversely, when I leave the spaceship (so that the camera movement must become limited to the horizontal plane) I do this:

Code: Select all

camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.025f,-1,keyMap,4,true,0.f);
I do the same thing whenever an element of the GUI (that is already present) must display something different. For example, when I go from a planet to another, I do this:

Code: Select all

gcp=guienv->addImage(guiplanets[planet],core::position2d<s32>(0,0));
so that the name of the old planet is replaced by the name of the new one.

Now, this works, but I find it inefficient, especially in the case of the GUI, because it keeps adding objects over objects and eventually the performance slows down to a crawl. I once made a stress test where a new GUI image was added not just when it needed to be changed, but once per cycle. As a result, in few minutes the framerate went below one frame per second.
How do I avoid this? Is there a way to change some of the properties of an existing object (in my case, the keymap size and vertical movement for the camera, and the image for the GUI) without adding it again?
Luben
Posts: 568
Joined: Sun Oct 09, 2005 10:12 am
Location: #irrlicht @freenode

Post by Luben »

You can add the gui elements once, and the toggle visibility for them with IGUIElement::setVisible, and likewise for cameras, you can toggle which one you want to use with ISceneManager::setActiveCamera.

You could also remove the old elements before adding new ones, or check if there are functions to change properties of nodes / elements, like IGUIImage::setImage
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Post by Devil Master »

Thank you, the setImage function is what I needed. Shame that there are no functions to change the camera parameters I had mentioned, though, and that I have to use multiple cameras.
TCM
Posts: 53
Joined: Mon May 24, 2010 9:29 pm

Post by TCM »

It might make sense to create two custom classes (but derived from the same base class). Each one will have it's own camera. when you select from one to another, each element will have it's associated camera.

More than one camera can co-exist. You just select which camera is active at a moment. You do not need to delete one camera that does not show up. But also there is no need to create another.
Devil Master
Posts: 81
Joined: Wed Apr 23, 2008 8:47 pm

Post by Devil Master »

I'm still perplexed about a couple of things about multiple cameras.
Right now, the camera movement routines always assume that the active camera is called "camera". I added a second camera called "cameravehicle", and I thought of two possible ways not to change (or to change as little as possible) the camera movements routines:
1) add "cameravehicle" as a child of "camera"
2) add a condition where, if "cameravehicle" is active, it is repositioned to the coordinates of "camera" once per cycle

Problems:
1) the first method does not allow "cameravehicle" to rotate independently. Why? I thought objects in a hierarchy would still be able to rotate independently from their parents, and the hierarchy only affected translations
2) the second method "kinda" works, but if I switch from the first camera (a standard FPS camera, controlled by its keymap) to the second (still an FPS camera in order to rotate it with the mouse, but the translations are handled by custom functions) while a movement key is being pressed, the first camera keeps moving in the same direction even when it's no longer the active camera and I'm no longer pressing the key. As a result, the second camera follows the movement of the first (as it should), but in this case the first camera should not move at all because the key that made it move has been released! How do I prevent this from happening?

I also thought of a third possible solution: to modify the movement routines so that, instead of always referring to one camera, they refer to the camera that is currently active. But how do I detect the currently active camera? Is there a way to do it automatically without adding lines where the value of a variable is changed every time the active camera is changed?
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

You could create empty nodes, and position/parent the camera when the need arise. Also for most of the camera you can "bind" the rotation with the target.
Post Reply