Page 1 of 1

Incorrect Camera/Mesh movement

Posted: Sat Mar 08, 2008 8:24 pm
by ktyrer496
hi,

i am creating a ship which will move through the level with the camera following it, when i first start moving and when i stop moving its very 'jerky' but once its going its. when i stop it seems to move back a place rather than stop. ive been told it could be somehting to do with the camera not updating enough btu i cant find a problem and im not sure this is the fault, my code is as follows any help would be nice!

cheers


my keypress code

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
		if (Navigator != 0 && event.EventType ==   irr::EET_KEY_INPUT_EVENT)
		{
			core::vector3df v = Navigator->getPosition();
			switch(event.KeyInput.Key)
			{
			case KEY_KEY_W:
			case KEY_KEY_S:
				{
					v.Y +=event.KeyInput.Key == KEY_KEY_W ? +4.0f : -4.0f;
					Navigator->setPosition(v);
				}
				return true;
			case KEY_KEY_A:
			case KEY_KEY_D:
				{
					v.X += event.KeyInput.Key == KEY_KEY_A ? -4.0f : +4.0f;
					Navigator->setPosition(v);
				}
				return true;
			}

		}
		
		return false;
	}
};
and my camera code

Code: Select all

		vector3df NavigatorRot = Navigator->getRotation();
		vector3df NavigatorPos = Navigator->getPosition();

		float DirY = NavigatorRot.Y + (90 * 3.14) / 180; //original 3.14
		float CamX = (NavigatorPos.X - cos(DirY)*45);
		float CamZ = (NavigatorPos.Z - sin(DirY)*35);
		float CamY = (NavigatorPos.Y + 5);
		camera = smgr->addCameraSceneNode();
		camera->setTarget(NavigatorPos);
		camera->setPosition( vector3df( CamX, CamY, CamZ ) );
im using
Navigator->setPosition(v);
to update the ship position

also im getin very low FPS at aorund 15-19, is there a reason for this there isnt much in the scene but surely this isnt right

thanks again for any help

Posted: Sat Mar 08, 2008 10:49 pm
by JP
What's the poly count in your scene? That's one reason it could be low.

It may be your event receiver code causing your movement problems, ideally you'd want to be using the sort of code shown in MastEventReceiver in the wiki (link on the main irrlicht page), that will give you nice smooth key responses rather than what you can get with your code which will move the node once when you hold down a key and then pause for a second and then start moving continuously, is that what you're getting?

EDIT: oh and a good thing to do after setting the camera's position is to call camera->updateAbsolutePosition(). I don't know if the need for that has now been fixed but in previous versions of irrlicht it was certainly necessary to get nice smooth camera movements.

Posted: Sun Mar 09, 2008 11:31 am
by ktyrer496
cheers for that, yeah im getting exactly that i press once it goes one space then continues after a few milliseconds, ill give that a try, im not sur eon the poly count im told it theres not a lot because our designer has lowered al poly ocunt on hte models, and as far as i can remeber ti was like this when i had next to nothing in the scene.

cheers for the help ill let you know how it goes

Posted: Sun Mar 09, 2008 4:31 pm
by rogerborg
ktyrer496 wrote:cheers for that, yeah im getting exactly that i press once it goes one space then continues after a few milliseconds, ill give that a try,
In any text editor, hold down a key and see what happens on your screen.

Does that behaviour look familiar? See what's happening? ;)

Example 04.Movement has been updated to demonstrate how to store and act on the state of a key, rather than just on the state change. If you don't have that version yet, then here's the event receiver:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
	// This is the one method that we have to implement
	virtual bool OnEvent(const SEvent& event)
	{
		// Remember whether each key is down or up
		if (event.EventType == irr::EET_KEY_INPUT_EVENT)
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

		return false;
	}

	// This is used to check whether a key is being held down
	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:
	// We use this array to store the current state of each key
	bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
And here's how it's used inside the main game loop:

Code: Select all

		if(receiver.IsKeyDown(irr::KEY_KEY_W))
		{
			core::vector3df v = node->getPosition();
			v.Y += 0.02f;
			node->setPosition(v);
		}
		else if(receiver.IsKeyDown(irr::KEY_KEY_S))
		{
			core::vector3df v = node->getPosition();
			v.Y -= 0.02f;
			node->setPosition(v);
		}

Posted: Sun Mar 09, 2008 5:15 pm
by ktyrer496
worked an absolute treat,

thanks for the help

Posted: Sun Mar 09, 2008 5:35 pm
by JP
Ahh glad to see the movement tutorial has been updated as it really was a bad example and threw off a lot of pepople!

Now we just need to get those online tutorials updated! :lol:

Posted: Sun Mar 09, 2008 5:37 pm
by rogerborg
n/p, this catches a lot of people out. That's why we've put it in the SDK examples now. ;)

Posted: Wed Apr 23, 2008 6:25 pm
by lenx
Hi there,
Sorry to bump this month old thread but the issue i'm dealing with right now fits exactly in here!

I'm working on something which basically works the same as the example above. That is, when a key is pressed, the position of my character is updated with the "position += speed" method.

Now it came to my mind that the real speed as seen ingame is depending on the game loop speed / CPU speed. Is that so?

So i tried this (kinda pseudo code):

Code: Select all

u32 currentTime = m_pDevice->getTimer()->getRealTime();
if(currentTime > u32TimeFlag + 30)
{
    u32TimeFlag = currentTime;
    position += speed;
}
Now the position should be updated every 30 ms which is about 30 fps, but movement is jerky at moments! It's only smooth when i set it to a 1ms or 2ms delay, which led me to the discovery that the movement is only smooth when the game loop takes longer than the "waiting for a new update time" of this code.

This doesn't make sense at all to me! When this updating loop is performed every 30ms (and it is), movement should be smooth! Can someone please shed some light on this :)