Radar in Arras Demo

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.
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Radar in Arras Demo

Post by JRS »

Hey,

I modified arras Shifted Tiled Terrain Scene Node for a project of mine and because the terrain is soo big I tried to implement a little radar that shows where the camera is on the map.

I did it like this:

Code: Select all

    video::ITexture* dot=driver->getTexture("Media/dot.bmp");
    video::ITexture* map=driver->getTexture("Media/Map.jpg");

	while(device->run())
    {
        driver->beginScene(true, true, video::SColor(255,100,101,140));

        // calculate time between frames
        oldtime = time;
        time = (f32)timer->getTime() / 1000.0f;
        deltaT = time - oldtime;

        // camera movement control
        if(key.pressed(KEY_KEY_W)) camera.moveForward(speed * deltaT);
        if(key.pressed(KEY_KEY_S)) camera.moveBack(speed * deltaT);
        if(key.pressed(KEY_KEY_D)) camera.moveRight(speed * deltaT);
        if(key.pressed(KEY_KEY_A)) camera.moveLeft(speed * deltaT);

        // mouse directional control
        camera.turnRight(50 * (device->getCursorControl()->getRelativePosition().X - 0.5f));
        camera.turnUp(50 * (device->getCursorControl()->getRelativePosition().Y - 0.5f));
        device->getCursorControl()->setPosition(0.5f, 0.5f);
        device->getCursorControl()->setVisible(false);

.
.
.

        swprintf(tmp, 1024, L"camera position: %i, %i, %i,", (s32)camera.getPosition().X, (s32)camera.getPosition().Y, (s32)camera.getPosition().Z);
        font->draw(tmp, core::rect<s32>( 10, 50, 400, 60 ), video::SColor(255,255,255,255));

        swprintf(tmp, 1024, L"camera heading: %i", (s32)camera.getHeading());
        font->draw(tmp, core::rect<s32>( 10, 70, 400, 80 ), video::SColor(255,255,255,255));

        u32 prm = driver->getPrimitiveCountDrawn();
        swprintf(tmp, 1024, L"primitives: %i", prm );
        font->draw(tmp, core::rect<s32>( 10, 90, 300, 100 ), video::SColor(255,255,255,255));


        // Add Terrainradar

        guienv->addImage(map,core::position2d<s32>(590,10));//Map for radar
        guienv->addImage(dot,core::position2d<s32>(((s32)camera.getPosition().X/10)+590-3,210-((s32)camera.getPosition().Z/10)-3));


.
.
.
And it works. But when I do this the FPS goes down... In the end I get FPS of 4. This really sucks.
I think it's because I have to load the texture with every step and so my memory gets fuller and fuller.

I tried to do my code at some other points of the program but it doesn't work.

Has anybody an idea how to do this without killing my memory :roll:

Thank you very much,
regards,

Jan
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

You're adding a new radar every single frame... are you sure this is necessary? ;)

Suggest you move the gui->addImage bits to before the render loop!

GUI elements have a move() function which you can use to move the dot image to the camera's location.
Image Image Image
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Hi, could this be added BEFORE the loop? (while(device->run()) )

Code: Select all

// Add Terrainradar 

        guienv->addImage(map,core::position2d<s32>(590,10));//Map for radar 
        guienv->addImage(dot,core::position2d<s32>(((s32)camera.getPosition().X/10)+590-3,210-((s32)camera.getPosition().Z/10)-3)); 
I think you're adding a lots if images (the same overlay over the same position). I think node and memory usage will increase the more time your application is running. You use the method addImage, that is will add an image node on the GUI manager.

For the dot, JP is right.

For the position and heading, you could create a temporary value that store the old value and compare it to the new, if they are different, you draw the font, if they are the same, you don't draw them. (A simple IF statement with a check for this)
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

christian, font->draw has to be called every frame if you want it to be rendered, it's not like an element or node which remains. There's no problem with his font->draw code, just the addImage()s every single frame.
Image Image Image
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Well,

thank you for the FAST reply!

@ JP:
Well I don't have to add the map every single frame but the dot is necessary or am I wrong?
I want a dynamic Dot that moves over the terrain as I do...
Ok the suggestion about the move() function is very good. I'll try this ;)
I hope it'll work :?

@ christianclavet:
I tried it. I tried to insert at least everything but

Code: Select all

guienv->addImage(dot,core::position2d<s32>(((s32)camera.getPosition().X/10)+590-3,210-((s32)camera.getPosition().Z/10)-3)); 
before the loop, because I don't want the map to reload every frame but there was always an error in the program and it crashed.
How can I do this temporary? (Sorry I'm quite a noob ;) )

@ all ;)
Why does the program crash if I try to insert the picture before the loop??
This is what I don't get :(

Well, again: Thank you!
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

are you sure your camera isn't a pointer?

you have to add the image after your camera anyway as you're using its position.

can you show your camera creation code?
Image Image Image
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Of course I can ;)

here it is:

Code: Select all

	MCameraFPS camera(smgr);
	camera.setNearValue(0.1f);
	camera.setFarValue(tileSize*meshSize/2);
	camera.setPosition(core::vector3df(terrainWidth*tileSize/2, 0, terrainHeight*tileSize/2) + terrainPos);
And it ist based on the MCameraFPS.h (just look in arras New Tiled Terrain Scene Node ;))

Now I set both guienv->... BEFORE the loop.
It works but how does move() work?

Well I think I'll find this somewhere.

I'll try to set a move() command where the guienv->... code was before.

Hope this works.

By the way. Can I include an transparent picture into Irrlicht? I tried to load a if but it doesn't work.
Last edited by JRS on Wed Jul 30, 2008 7:29 pm, edited 1 time in total.
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

yeah you can use transparent textures, PNG is one transparent format which irrlicht loads, the main irrlicht page -> features will tell you what texture formats are supported.

move() i think takes a position2di which is the amount it should be moved by so you'll have to work out the change in camera position since the previous frame and pass that as a position2di (check the API/docs to be sure that i'm right ;))
Image Image Image
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Thanks!

I think you're right but I'll check it out.
With transparent textures I now used TGAs this works well ;)

Now I'll try and then I will tell you more :D
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Yeah you were right.

move() takes a position2d<s32>
But how can I do this.

Code: Select all

guienv->addImage(dot,core::position2d<s32>(590+100-2,10+100-2));
is an IGUIEnvironment and move() works for IGUIElement.
Last edited by JRS on Wed Jul 30, 2008 5:45 pm, edited 1 time in total.
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Ok I got it ;)

Sorry for some stupid questions.

Now I only have to find my absolut movement.
This is what I'll try now :)
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

I tried this:

Code: Select all

       core::vector2d<s32> movement;
        movement=core::vector2d<s32>(terrainWidth*tileSize/2, terrainHeight*tileSize/2);
        movement=(core::vector2d<s32>((s32)camera.getPosition().X,(s32)camera.getPosition().Z)-movement);
        point->move(movement);

But there is the Problem that move() isn't declared for IGUIImage...

point is defined like this:

Code: Select all

gui::IGUIImage* point=guienv->addImage(dot,core::position2d<s32>(590+100-2,10+100-2));
point;
Any ideas?

Thanks :P
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Finally it nearly works!

My only problem is the movement part.
I got this:

Code: Select all

core::position2d<s32> movement;
        movement=core::position2d<s32>(terrainWidth*tileSize/20, terrainHeight*tileSize/20);
        movement=(core::position2d<s32>((s32)camera.getPosition().X/10,(s32)camera.getPosition().Z/10)-movement);
        point->move(movement);
The direction of the movement is always (0,1). But it doesn't stop.
I think the problem is in
movement=(core::position2d<s32>((s32)camera.getPosition().X/10,(s32)camera.getPosition().Z/10)-movement);
But how can I do it better?
I hope there is anybody online. I'll hang on ;)
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I think you probably want to use setRelativePosition() instead. That would set the position of the element relative to the parent. The move() method will offset the position by a given distance.
JRS
Posts: 45
Joined: Tue Jun 03, 2008 10:00 am
Location: Universität Heidelberg

Post by JRS »

Ok, thanks I'll try this.
But what argument should I give to SetRelativePostition?
I know that it take a const core::rect< s32 > but what is it?
I think I have to study this option tomorrow...

It should be, if the camera moves something like (x,y,z) then the dot should move (x/10,z/10)...

Hope I'll get this.
Post Reply