Smooth FPS camera

A forum to store posts deemed exceptionally wise and useful
warui
Posts: 232
Joined: Wed Apr 14, 2004 12:06 pm
Location: Lodz, Poland
Contact:

Smooth FPS camera

Post by warui »

Hi!

As we all know rotation in Irrlichts default cameras is really jerky. There are two reasons for that:
1) small mouse position changes are not regonized
2) rotation angle may differ between frames because of aproximation (ex: if you move your mouse with a speed of 3.5 pixels per frame in one frame it will be treated as you had moved 3 pixel and in next frame as 4 pixels)

Ad.1
Quite easy to fix. Just change this lines in
CCameraFPSSceneNode::animate() (CCameraFPSSceneNode.cpp)

Code: Select all

if (cursorpos.X < 0.49f || cursorpos.X > 0.51f ||
    cursorpos.Y < 0.49f || cursorpos.Y > 0.51f)
to

Code: Select all

if (cursorpos.X < 0.5f || cursorpos.X > 0.5f ||
    cursorpos.Y < 0.5f || cursorpos.Y > 0.5f)
Ad.2
The way to solve this is taking average mouse posiotion change of last 3 frames instead of only last one.

First we have to add to tables to hold last two mouse positions and a variable to checkif it is the first time we make rotation. Just put this into CCameraFPSSceneNode definition (CCameraFPSSceneNode.h)

Code: Select all

f32 rotX[3];
f32 rotY[3];
bool firstRot;
Then in CCameraFPSSceneNode::animate() (CCameraFPSSceneNode.cpp) change the following:

Code: Select all

	// Update rotation

	Target.set(0,0,1);

	if (!CursorControl)
		return;

	RelativeRotation.X *= -1.0f;
	RelativeRotation.Y *= -1.0f;

	if (InputReceiverEnabled)
	{
		core::position2d<f32> cursorpos = CursorControl->getRelativePosition();
		
		if(firstRot) // it checks if it is the first time camera rotates and than fill tables with proper values
		{
      rotX[0] = rotX[1] = 0.5f - cursorpos.X;
      rotY[0] = rotY[1] = 0.5f - cursorpos.Y;
      firstRot=false;
		}
		
		rotX[2] = 0.5f - cursorpos.X; // puts values from this frame
		rotY[2] = 0.5f - cursorpos.Y;// into table

		if (cursorpos.X < 0.5 || cursorpos.X > 0.5 ||
			cursorpos.Y < 0.5 || cursorpos.Y > 0.5 )
		{
			RelativeRotation.Y += (rotX[0]+rotX[1]+rotX[2])/3 * RotateSpeed; // here we use the average value i mentioned before
			RelativeRotation.X += (rotY[0]+rotY[1]+rotY[2])/3 * RotateSpeed; // and here too ;)
			CursorControl->setPosition(0.5f, 0.5f);

			if (RelativeRotation.X > 89.0f) RelativeRotation.X = 89.0f;
			if (RelativeRotation.X < -89.0f) RelativeRotation.X = -89.0f;
		}
		
		rotX[0] = rotX[1]; // finaly we move values to make room for a new ones
		rotX[1] = rotX[2];
		
		rotY[0] = rotY[1];
		rotY[1] = rotY[2];
	}

	// set target
Now compile and enjoy smooth rotation :) It's still not perfect but works well most of the time.

If you find some bugs or have some improvements i'll be glad to read them.

To Nico: How about adding it to SDK ? And another thing. Why default value for FOV is set to 45 degrees ? With it camera works like in alien mode form AvP ;) Set it to 90 or something. I know it's easy to change via FOV(), but some newbies might have problems with "what's wrong with the camer" while watching techdemo or examples.
Tomasz Nowakowski
Openoko - www.openoko.pl
afecelis
Admin
Posts: 3075
Joined: Sun Feb 22, 2004 10:44 pm
Location: Colombia
Contact:

Post by afecelis »

thnx for that code warui! I tried it and indeed it makes the camera much smoother!!

sweet!

I merged it into my Irrlich source and made it my standard!!

great!! i

I'm using it here:
http://irrlicht.sourceforge.net/phpBB2/ ... php?t=2538
Image
warui
Posts: 232
Joined: Wed Apr 14, 2004 12:06 pm
Location: Lodz, Poland
Contact:

Post by warui »

I'm glad someone found it useful.
Tomasz Nowakowski
Openoko - www.openoko.pl
afecelis
Admin
Posts: 3075
Joined: Sun Feb 22, 2004 10:44 pm
Location: Colombia
Contact:

Post by afecelis »

more than useful, it's kick ass!

thnx thnx thnx
Image
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

hmm, camera already works good i think so
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

VeneX wrote:hmm, camera already works good i think so
Nah, just tested with the 2 different dll's. The original one doesn't react when I move my mouse a little bit. The second (with this code) does.
But I have another problem with the FPS-cam. I changed the FOV-value to 90 like some ppl told me. The strange effect is gone but now the camera is like "zoomed in".

Screens do tell 1000 words :P:

FOV45 (good view but moving mouse up/down doesn't seem to be correct)
Image

FOV90 (correct up/down moving but view is weird, it's like they pushed on top and bottom)
Image

Pictures are made on exactly the same position.
Darklance
Posts: 5
Joined: Mon Jul 12, 2004 4:54 am

Post by Darklance »

That certainly sounds useful....can you provide a compiled dll/lib of this fix? I'm not sure how to compile them myself.
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

Post by thesmileman »

bal, I could be wrong but the second image looks exactly like I would expect after lowering your field of view.
Rocketeer
Posts: 9
Joined: Sun Jul 11, 2004 9:13 am
Contact:

Post by Rocketeer »

thesmileman wrote:bal, I could be wrong but the second image looks exactly like I would expect after lowering your field of view.
Now I'm confused... hasn't he just increased the FOV from 45 to 90?
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

thesmileman wrote:bal, I could be wrong but the second image looks exactly like I would expect after lowering your field of view.
It looks good, but just test it yourself. If you move the mouse you'll feel that it is like you zoomed in.
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

Post by thesmileman »

I tested it in a couple of my applications and while it does feel somewhat as though it is zoomed in I would expect that to be the case when you cange the field of view a considerable amount. have you tried a number for FOV in the middle of the two?
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

Post by thesmileman »

I tested it in a couple of my applications and while it does feel somewhat as though it is zoomed in I would expect that to be the case when you cange the field of view a considerable amount. have you tried a number for FOV in the middle of the two?
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

Yes. 60 and 80 made the view completely f*cked up.

But how do the engines of real FPS-games handle this?
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
Captain_Kill
Posts: 124
Joined: Sun Jun 27, 2004 11:02 am
Contact:

Post by Captain_Kill »

I'm suprised people haven't noticed this Irrlicht 'difference'... Specifying degrees like 90 or 80 is wrong :shock: If you check the docs for setFOV you'll see that you actually use fractions, eg. 1.4 is around normal for an FPS view. Yes it is weird and it did take me a while to figure out but I'm positive that's how Irrlicht handles FOV
2.8GHz P4 with HT - 512MB DDR - ATI Radeon 9600XT 256MB - Windows XP - VC++ 6 and VC++ 2003

Dark Reign 3 Home Page: http://darkreign3.notwhatyouthink.org/
Dark Reign 3 Forums: http://notwhatyouthink.org/darkreign3bb/
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

Omg, thx a lot Captain_Kill :D
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
Post Reply