Easiest 3rd Person Camera

A forum to store posts deemed exceptionally wise and useful
Post Reply
mepcotterell
Posts: 10
Joined: Thu Dec 29, 2005 2:42 pm

Easiest 3rd Person Camera

Post by mepcotterell »

I decided that making the camera a child of the playernode was not the best idea because it restricts what you can do with the camera. Keeping that in mind I wrote a little bit of code to make the camera follow a character, position itselft and rotate appropriately based on the platernodes position and roatation. As an added bonus I'll also include code on how to modify the player node to move appropriatley with rotation.

To use the trigonometric funtions like sin and cos you need to include the standard math headers by putting the following at the top of you code.

Code: Select all

#include <math.h>
Fist off, this code goes into the render loop before the draw functions are called.

Code: Select all

         int cOffset = 0; // change this to rotate the camera around the character
         int cZoom = 200; // radius.. decrease to zoom in, increase to zoom out

         core::vector3df r = playernode->getRotation();
         core::vector3df p = playernode->getPosition();

         camera->setTarget( core::vector3df( playernode->getPosition() ) );
         camera->setPosition(
            core::vector3df(
               ( -1 * cZoom * cos( -1 * ( r.Y + cOffset ) * 3.14159265/180 ) ) + p.X,
               p.Y+50,
               ( -1 * cZoom * sin( -1 * ( r.Y + cOffset ) * 3.14159265/180 ) ) + p.Z
            )
         ); 
What it did: It set the camera target to the position of the playernode. Then it used trigonetry to place the camera relatively behind the playernode using the playernodes rototation as a factor and put the camera at a distance of cZoom.

Next, wherever you handle key events declare a position and rotation variable based on the player node. Also define some speed that the playernode will move with.

Code: Select all

      float speed  = 4.0; 
      core::vector3df r = playernode->getRotation();
      core::vector3df v = playernode->getPosition();
Then you would put the following code in its appropriate conditional.

What it will do: It will move the playernode about the X,Z axis while repecting the nodes rotation. Meaning that if a character is rotated x degrees to the right or left and movement is called then the node will move while keeping the persoective of the node. It will move forward in the direction the node is facing basically.

Forward:

Code: Select all

		v.X = v.X + ( cos(r.Y * 3.14159265/180)*speed );
		v.Z = v.Z - ( sin(r.Y * 3.14159265/180)*speed );
		playernode->setPosition(v);
Reverse:

Code: Select all

		v.X = v.X - ( cos(r.Y * 3.14159265/180)*speed );
		v.Z = v.Z + ( sin(r.Y * 3.14159265/180)*speed );
		playernode->setPosition(v);
Strafe Left:

Code: Select all

		v.X = v.X + ( cos((r.Y-90) * 3.14159265/180)*speed );
		v.Z = v.Z - ( sin((r.Y-90) * 3.14159265/180)*speed );
		playernode->setPosition(v);
Strafe Right:

Code: Select all

		v.X = v.X + ( cos((r.Y+90) * 3.14159265/180)*speed );
		v.Z = v.Z - ( sin((r.Y+90) * 3.14159265/180)*speed );
		playernode->setPosition(v);
Turn Left:

Code: Select all

		r.Y = r.Y - 4.0f;
		playernode->setRotation(r);
Turn Right:

Code: Select all

		r.Y = r.Y + 4.0f;
		playernode->setRotation(r);
----------------

I hope that helped some people; especially those who have either needed a third person camera and couldn't get one to work and those who aren't comfortable with trigonometry.
hybrid

Post by hybrid »

Instead of putting the update code into the main loop it might be a good idea to out it into onPostRender of some new CameraSceneNode. Check IrrSprintz for such a 3rd Person CameraSceneNode. He also added some new key interface which enables event based movements for the scene node.
BTW: Irrlicht has some constants for PI, PI/180 etc.
mepcotterell
Posts: 10
Joined: Thu Dec 29, 2005 2:42 pm

Post by mepcotterell »

This was just a quick 3rd person set up... onPostRender eh? I'll look into that.
mepcotterell
Posts: 10
Joined: Thu Dec 29, 2005 2:42 pm

Post by mepcotterell »

I made a little diagram so that people can maybe better understand the trigonomety involved...

Image

of course in the code the roation is given in degrees and you have to convert those degrees to radians in order to take the sin or cos of them. to do this you multiple the degree by pi divided 180.

in the above diagram the camera will show up in front of the player node. if you want the camera behind the player node then just use the negative coordinates for x and z
tjuhzj
Posts: 44
Joined: Mon Mar 27, 2006 7:00 am

??

Post by tjuhzj »

i am afraid that your player node would be able to walk through the terrain!

additionally , i wonder if the CollisionResponseAnimator will Collide with your self-defined Player node??
________
Toyota bb specifications
Last edited by tjuhzj on Fri Feb 25, 2011 4:36 am, edited 1 time in total.
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Post by Strong99 »

where to put the

v.X = v.X + ( cos(r.Y * 3.14159265/180)*speed );
v.Z = v.Z - ( sin(r.Y * 3.14159265/180)*speed );
playernode->setPosition(v);

???
persoontje
Posts: 2
Joined: Sat Mar 25, 2006 8:47 pm

Post by persoontje »

mepcotterell wrote:I made a little diagram so that people can maybe better understand the trigonomety involved...


of course in the code the roation is given in degrees and you have to convert those degrees to radians in order to take the sin or cos of them. to do this you multiple the degree by pi divided 180.

in the above diagram the camera will show up in front of the player node. if you want the camera behind the player node then just use the negative coordinates for x and z
Can you upload this picture again? I can't see it now.
Godl1ke
Posts: 4
Joined: Thu Aug 03, 2006 5:08 am

Post by Godl1ke »

Okay im trying this out...
but when im compiling it it gives me an error
playernode not defined in scope (I changed my MD2 object to playernode)
and camera not defined in scope....
any help please?!

EDIT :: Okay DW I Fixed it anyway now...
Post Reply