Why is the camera movement so slow?

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.
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Why is the camera movement so slow?

Post by Noiecity »

When I press a key to move the location camera, it takes a long time from my perspective, for example, if I press W or the up arrow, it takes approximately 20ms to 30ms to respond, which, for me, is a lot, in counter strike 1.6 normally the response will seem immediate as it does between 1ms to 3ms.

I also noticed this slowness in the official irrlicht example projects, I haven't looked at the engine code, but I must assume it has to do with some functionality added to the move in your loop.

I don't want it to take so long, I mean, maybe most of you won't care, but I want to build a shooter in irrlicht, irrlicht so far has shown excellent performance, superior to all the engines I've tried so far (to build retro 3d games), at the level of unreal engine 2 and probably higher than it (unreal 3 versions onwards have lousy performance for retro 3d applications), but I don't know how to solve the issue of the delay when moving in irrlicht
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Why is the camera movement so slow?

Post by CuteAlien »

The way event handling should happen is:
- Key press is send to the system (Windows or Linux).
- Irrlicht calls run() at the start of your game loop to evaluate all messages in the event-buffer of the system.
-This will internally call CSceneNodeAnimatorCameraFPS::OnEvent which remembers if the button is pressed or not.
- CSceneManager::drawAll() will call CSceneNodeAnimatorCameraFPS::animateNode which evaluates that info and when the key is pressed immediately moves the camera
So basically evaluation of events and animation all happens in the same frame.

I couldn't reproduce the problem here (just tested it on Linux), but I got some idea what might be going wrong after looking at the code of CSceneNodeAnimatorCameraFPS:
It buffers the state of key pressed/not pressed when handling events. But not sure if key-repeat behaviour is that well defined. Doing a quick test here I noticed that I get on X11 for example I get several key-down events and the occasional key-up event. The amount of down events until I got an up event seemed near random. Thought as long as the key was pressed I always got another down event after the up event in the same frame so the animation later should be correct.

I'll test tomorrow on Windows how it behaves there. Possible buffering at that point is not correct and one would have to use a function like GetKeyboardState inside animateNode (bit tricky as that is not platform independent... would need a similar wrapper for all platforms then in Irrlicht).

My test for experiments:

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

class MyEventReceiver : public IEventReceiver
{
	public:
	MyEventReceiver() : anyEvent(false) {}
	bool anyEvent;
	bool OnEvent( const SEvent &event )
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			if( event.KeyInput.PressedDown )
			{
				anyEvent = true;
				std::cout << "PressedDown:" << event.KeyInput.Key <<  " shift:" <<  event.KeyInput.Shift << std::endl;
			}
			else if( !event.KeyInput.PressedDown )
			{
				anyEvent = true;
				std::cout << "!PressedDown:" << event.KeyInput.Key << " shift:" <<  event.KeyInput.Shift<< std::endl;
			}
		}

		return false;
	}
};

int main()
{
	SIrrlichtCreationParameters params;
	params.WindowSize = core::dimension2d<u32>(640, 480);
	params.DriverType = video::EDT_OPENGL;
	IrrlichtDevice * device = createDeviceEx(params);
	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	MyEventReceiver receiver;
	device->setEventReceiver(&receiver);

	while(device->run() && driver)
	{
		if ( receiver.anyEvent )
		{
			std::cout << "frame" << std::endl;
			receiver.anyEvent = false;
		}
	}

	device->drop();

	return 0;
}
Not quite sure what to do if that is the problem. If you have only one platform to support you could use your own camera animator which doesn't buffer key-presses before the animation (recommended anyway sooner or later when doing a real game).
Or I think key repeat behavior can also be controlled a bit (not from Irrlicht, but directly with system calls). But I haven't experimented with that yet.

If it's not the problem... (and I don't really think it is, just guessing it might maybe be a problem on some systems) then maybe it's not related to Irrlicht? Could it be you got some other tool running which buffers events? For example some macro software running (gamers sometimes have all kind of stuff like that).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

I mean, when I press the response speed, it's relatively normal, not fast, but it's not like it stops or something, just that 20 ms is too much, in a shooter it's equivalent to being shot at least once, I did the tests on a old laptop and a better one, practically formatted and updated, I mean, when you open the example that irrlicht gives you can see in the examples, the camera movement has a delay (in the examples it moves with the arrows), now, I installed cs 1.6 on both computers, and there is clearly a difference in response speed.

As I say, a casual player may not notice it, but for me 1 shot difference can mean the death of the player, that 20 ms could make the difference between moving and living, and being still and dying.

I also tried with the examples of the directx9 SDK where the camera could be moved, and also, the response is very fast, almost instantaneous, but in irrlicht for some reason it is a bit late, I mean, almost 20 times slower, it is How to move in an online game with slow internet, the answer takes time.

I had noticed that Irrlicht blurs the areas near the player, and I thought that some loop associated with the player's position affects that, because in directdraw for example, if you change the pointer to a sprite, it will automatically take longer to give the response when moving the pointer. pointer.

As I said, this may not matter, I was thinking of making a short animation to justify its lateness, after all it doesn't make the game unplayable, I just wanted to know the options or the reason why this was so, and I published here in the forum, I have also seen you answer several questions in the forum.

By the way, I am trying to use directx9 because it is the one that gives me the best results when it comes to obtaining high fps, more than opengl, I must assume that it has to do with how it processes directx textures.

The speed that I expected to move the camera was something like, I press the W key, and I didn't manage to blink my eyes and it has already moved, like in counter strike 1.6, but the result that I get based on irrlicht is that speed equals half a blink or blink

This is the code that my scene was working with, I still haven't figured out how to disable it so that it only moves with wasd and not the arrows hahaha:

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
		}
		return false;
	}

	virtual bool IsKeyDown(EKEY_CODE keyCode) const
	{
		return KeyIsDown[keyCode];
	}

	MyEventReceiver()
	{
		for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	}

private:
	bool KeyIsDown[KEY_KEY_CODES_COUNT];
};

int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // Cambiar a DirectX 9

	IrrlichtDevice* device = createDevice(
		driverType, core::dimension2d<u32>(800, 600), 32, true, false, true);

	if (!device)
		return 1;

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	MyEventReceiver receiver;
	device->setEventReceiver(&receiver);

	// load scene .irr
	smgr->loadScene("../../irrEdit-1.5/scenes/irrholi.irr");

	scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
	device->getCursorControl()->setVisible(false);

	int lastFPS = -1;

	while (device->run())
	{
		if (device->isWindowActive())
		{
			core::vector3df cameraPosition = camera->getPosition();
			core::vector3df moveDelta(0.f, 0.f, 0.f);

			float moveSpeed = 1.0f; // speed of movement

			if (receiver.IsKeyDown(KEY_KEY_W))
				moveDelta += camera->getTarget() - camera->getPosition();

			if (receiver.IsKeyDown(KEY_KEY_S))
				moveDelta -= camera->getTarget() - camera->getPosition();

			if (receiver.IsKeyDown(KEY_KEY_D))
				moveDelta += camera->getUpVector().crossProduct(camera->getTarget() - camera->getPosition());

			if (receiver.IsKeyDown(KEY_KEY_A))
				moveDelta -= camera->getUpVector().crossProduct(camera->getTarget() - camera->getPosition());

			moveDelta.normalize();
			moveDelta *= moveSpeed;

			cameraPosition += moveDelta;
			camera->setPosition(cameraPosition);

			driver->beginScene(true, true, video::SColor(255, 200, 200, 200));
			smgr->drawAll();
			driver->endScene();

			int fps = driver->getFPS();

			if (lastFPS != fps)
			{
				core::stringw str = L"Irrlicht Engine - example movement camera [";
				str += driver->getName();
				str += "] FPS:";
				str += fps;

				device->setWindowCaption(str.c_str());
				lastFPS = fps;
			}
		}
		else
			device->yield();
	}

	device->drop();
	return 0;
}
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

As I say, the response is fast, but if you are a shooter player you will notice that it is slow in comparison, since for example, in counter strike 1.6 it fires right after the character stops because it always goes to the center shot, so if you practice moving in irrlicht to calculate the shot, you realize when you stop the camera that it slows you down than in counter strike 1.6, this technique is known as "tapping", since in games like counter strike 1.6 the movement affects the shot, that is, if the character is moving the "recoil" will be different than when you shoot right after moving.

That's why I say, most of you wouldn't notice it, my self from 3 years ago wouldn't notice that irrlicht is slow compared to cs 1.6 in terms of input response (in general irrlicht is better than sdl2 with opengl)
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Why is the camera movement so slow?

Post by CuteAlien »

OK, not much time right now (lunch pause), but some quick info.
First, my test showed that my original idea doesn't seem to be the problem on Windows either. So let's ignore that for now.

I do not have irrholi.irr, but testing with media/example.irr I don't really notice anything. Maybe my lack of CS training?

DirectX or OpenGL should be completely unrelated to this. Either the key event is handled same frame or not, everything else shouldn't be noticable with tiny scenes where the FPS is likely only limited by your screen (unless your test-scene is huge and has a slower fps?).

It's often not the best idea to mix camera animators with manual movement code (they now both try to move the camera). Thought I guess for this specific problem it does not matter.

Your code is different from Irrlichts movement code as yours is not frame independent. Irrlicht multiplies speed by milliseconds since last frame.
Note that it uses virtual time (getTime instead of getRealTime) in animations, so that means it only gets updated once per frame (in device->run()). Which gives you a tiny delay, but has the advantage of every animator using the exact same time in a frame (and again not noticable if your fps is limited by your screen). Also more correct as time is from handling events in run() (while if you were to check current key-state inside OnAnimate you'd have to use real time - so yeah, up to 1 frame delay there... with low fps it could be noticable).

Keys to use for input are one of the parameters you can pass to addCameraSceneNodeFPS, check documentation for that one. Or example 21 - that one switches also to ASDW.

I hope we only talk about key-input here. Straight movement. Because mouse movement input in Irrlicht 1.8 had some delays in fps camera, those got fixed in Irrlicht svn trunk.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

Thanks for the info, that helps a lot
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

by the way, I had no performance problems, I was running at 1400 fps on an old pc with windows 7, if I had done the same scene in unity I would have had about 20 fps, in SDL2 about 110
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

Although in full screen I remember that it was limited to 60 fps according to the title that it showed me when I opened the task manager, but I still needed to see if that limit was due to changing the window or it was like that
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Why is the camera movement so slow?

Post by CuteAlien »

Exact 60 fps sounds like you have VSync enabled on a 60Hz screen. Either from Irrlicht (thought default is off, so unless you changed that it shouldn't be the case) or from graphic card (nvidia settings for example allow enabling vsync overriding game settings).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

i tried version 0.1 of irrlicht and the camera moves immediately, i mean, it doesn't seem to have any kind of lag, but i got 3 times less fps, and there were scenes that lag a lot despite having high FPS, i did these tests for the science hahaha but glad to see irrlicht has come so far from 0.1 to now
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

driverType, core::dimension2d<u32>(800, 600), 32, false, false, true);

true, i thought you needed to have both true to get full window, one was for windowed mode and the other enabled vsync apparently, though when i disable vsync the camera movement seems more jerky

driverType, core::dimension2d<u32>(800, 600), 32, false, false, false);


maybe the jerky movement when disabling vsync is due to occupying virtual time, but I'm not sure, I'll try without virtual time, but I'm not sure it will be better
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

I solved the problem with the movement difference between vsync off or on using the function that the irrlicht engine has apparently called getTimer()

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
		}
		return false;
	}

	virtual bool IsKeyDown(EKEY_CODE keyCode) const
	{
		return KeyIsDown[keyCode];
	}

	MyEventReceiver()
	{
		for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	}

private:
	bool KeyIsDown[KEY_KEY_CODES_COUNT];
};

int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // DirectX 9

	IrrlichtDevice* device = createDevice(
		driverType, core::dimension2d<u32>(800, 600), 32, false, false, false);

	if (!device)
		return 1;

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	MyEventReceiver receiver;
	device->setEventReceiver(&receiver);

	// load scene .irr
	smgr->loadScene("../../irrEdit-1.5/scenes/irrholi.irr");

	scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
	device->getCursorControl()->setVisible(false);

	int lastFPS = -1;

	// get the timer
	u32 lastTime = device->getTimer()->getTime();

	while (device->run())
	{
		if (device->isWindowActive())
		{
			// Calculate time elapsed since last frame
			const u32 currentTime = device->getTimer()->getTime();
			const f32 deltaTime = (currentTime - lastTime) / 1000.0f; // Convert to seconds
			lastTime = currentTime;

			core::vector3df cameraPosition = camera->getPosition();
			core::vector3df moveDelta(0.f, 0.f, 0.f);

			float moveSpeed = 50.0f; // Adjust movement speed

			if (receiver.IsKeyDown(KEY_KEY_W))
				moveDelta += camera->getTarget() - camera->getPosition();

			if (receiver.IsKeyDown(KEY_KEY_S))
				moveDelta -= camera->getTarget() - camera->getPosition();

			if (receiver.IsKeyDown(KEY_KEY_D))
				moveDelta += camera->getUpVector().crossProduct(camera->getTarget() - camera->getPosition());

			if (receiver.IsKeyDown(KEY_KEY_A))
				moveDelta -= camera->getUpVector().crossProduct(camera->getTarget() - camera->getPosition());

			moveDelta.normalize();

			// Calculate movement distance based on time and speed
			f32 distanceToMove = moveSpeed * deltaTime;
			moveDelta *= distanceToMove;

			cameraPosition += moveDelta;
			camera->setPosition(cameraPosition);

			driver->beginScene(true, true, video::SColor(255, 200, 200, 200));
			smgr->drawAll();
			driver->endScene();

			int fps = driver->getFPS();

			if (lastFPS != fps)
			{
				core::stringw str = L"Irrlicht Engine - movement example [";
				str += driver->getName();
				str += "] FPS:";
				str += fps;

				device->setWindowCaption(str.c_str());
				lastFPS = fps;
			}
		}
		else
			device->yield();
	}

	device->drop();
	return 0;
}
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Why is the camera movement so slow?

Post by CuteAlien »

Hm, never check out Irrlicht 0.1, that was a few years before I heard about this engine :)
But seems not to have a fps camera yet, how did you compare? Just using a non-fps camera with your code?
Maybe try that with current version as well, so avoiding any animator getting in the way (thought I still don't see how it can be a problem).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 92
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Why is the camera movement so slow?

Post by Noiecity »

in version 0.1 I saw an application created (Quake3Map.exe) that moved the camera with the left and right clicks, I noticed that the response was much faster, the difference is hardly noticeable perhaps, but it was much faster, it also seemed to have problems with moving diagonally haha
**
If you are looking for people with whom to develop your game, even to try functionalities, I can help you, free and in an anonymous way if necessary. You can send me a private message.

https://www.artstation.com/noiecty
**
CuteAlien
Admin
Posts: 9651
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Why is the camera movement so slow?

Post by CuteAlien »

That seems to use Maya camera.Which still exists (thought not useable for FPS games). But you can check it out by using addCameraSceneNodeMaya instead of addCameraSceneNodeFPS. Thought it seems to work a bit different than back in version 0.1 if I interpret the code correct. Because animation seems to have been called after rendering back then - so that should have 1 more frame delay than cameras have now. As by now animate (which evaluates the keys) is called before rendering.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply