Skip to main content
gamedev.net
🔒 Locked

third person camera

Started by u0_80 Jan 17, 2002 at 4:59 AM 7 replies 400+ views
Original Post
u0_80
u0_80
i want my camera to always follow the user...i have it working fine for forward, backward, and strafing, but i can''t figure out how to get it to stay directly behind the user when they rotate...i tried rotating the camera the same amount as the user, then moving it either way on the x axis, but this doesn''t work...any help?
Dark
Dark
I think your problem is that you are not using the Model''s matrix for the camera... you should use the coordinate system of the camera to calculate the new position... What I am trying to say is that hmm... ascii art


*

^
|



where * is the Model and the arrow is the direction of the camera... now if you try rotation (to the left by 90 degrees) this would give you


*

<-



and you wouldn''t see anything on the screen... this is because you use 2 separate coordinate systems

instead you should use the coordinate system of the model to calculate the new camera position (since the direction is always to the origin of the Model)...

How to do this... just imaging that you have 1 vertex somewhere to the back of the model (make sure to include it in the model''s vertex list that is transformed (by D3D or OpenGL)) but do not use that vertex in any face which builds up the Model... now when you rotate the model... that vertex is rotated too... so you can use its position for the camera''s origin... and the origin of the coordinate system (0,0,0) for the camera''s destination. Now if you get this idea... you probably know how do it without the extra vertex (but the extra vertex is the easy way)

I hope this is clear and has helped you with your problem

ICQ: 130925152
Email: e.j.folkertsma@student.utwente.nl
ICQ: 130925152Email: e.j.folkertsma@student.utwente.nl
u0_80
u0_80
if what you''re saying is to apply the same transformations ( rotations, etc ) to the camera as to the model, i have tried that...basically, what i believe i need is below:

*

^
|

that''s what i start with...now, when the user rotates, i need this:

* ( now facing north east )

/

so i tried applying the same rotation, and decrementing it''s x position, that didn''t work...any ideas?

thanks for the help, Dark...
u0_80
u0_80
the second drawing in my last post didn''t come out right...obviously, the camera should be behind and left of the model, looking it the same direction as the model...sorry about that...
UnshavenBastard
UnshavenBastard
some assumptions:
Y-axis is vertical, "top-->bottom" or "bottom-->top" of the screen
Z-axis points into screen (greater positive values mean further away)
v as prefix means Vector
Arithmetical operations on vectors are denoted with common operators (+,-)



you could define a distance vector the player and the camera.
let's first assume this vector vd is constant.
its length(magnitude) has the distance you want the camera away from the player.
It actually starts from the position where the camera is, and reaching with it's
"arrow top" until the player's position.
(just for imagination, don't get confused, continue reading!)

vd
P<-------C

vd doesn't need to have the same Y-direction as the viewing Y-direction of Player,
the camera could be a little above the player, thus, only x,z-values of vd
point into same direction (not necessarily equal numbers!)

_important_:
the original vector vd must be initialized with pointing into that direction,
that would correspond an Y-angle of zero degrees,
and it must never be changed, you store it, and use temporary vector to
calculate stuff with it...
(unless you want to change the camera's distance how much above the
player it is, but later on this...)




Every frame, you calculate the actual position of the camera _again_.
that would be:

vTemp = vd; // vd must be kept!
RotateVectorY(vTemp, PlayerAngle_Y); // rotate only Y-Direction !

vCameraPos = vPlayerPos - vTemp;

now you have the camera's position, on a line(at least in x,z) with
the Player.

you can always use the player's Y-angle as the camera's,
theyr're same. Well, but the camera's X-Angle may be different,
if you have the camera a little above and behind the player,
such that the camera is pointing slightly to the ground.

So the X-Angle must not be changed with player's rotation!


Now, if you want to change the camera's height, angle pointing more
up/down, and the distance to the camera:

Just make a Unit-vector of vd (scale by 1/magnitude),
and then scale it by the value of distance you want the cam to be away
from the player.
You could then rotate_X the vd to point is more up/down.(relative!)
Or, start with a new vector as vd, pointing with X-angle=zero, and magnitude=1,
then rotate it about the absolute X-angle you want the camera to look at.
(of course, in both cases, the Y-angle has to be zero, for it's
rotated every frame to get the Cameras actual current position,
as I said above !!)
( IE: vd.x=0; vd.y=0; vd.z=1; )





so you have a camera, which's distance and down/up-pointing angle
can change at any time. You can do smoth zoom-towards-player
and zoom-away-from-player effects, with changing the up/down-pointing
angle, quite nice.




If you have further questions, or can prove me that
I made a big mistake, please post!!
(I just created this solution for you, never used it myself.
well, but I'll store this textfile! ;-)



regards,
the unshaven bastard

(don't blame me, my razor got recently broken ;-)






Edited by - UnshavenBastard on January 17, 2002 7:51:54 AM
Mark Duffill
Mark Duffill
From the players world matrix,
Get the direction vector,
Get the up vector.

The cameras world position is (Direction * DIST) + (Up * UDIST);

DIST and UDIST been some float value.

Then simply do a lookat matrix from this point to the players point.

The resulting matrix is in world space, you''ll have to convert it to a "view" matrix by transposing it and the translation as follows:
  
D3DMATRIX World = Camera;
////////////////////////////////////////////////

// invert 3x3 part (transpose)

Camera.m[0][0] = World.m[0][0];
Camera.m[0][1] = World.m[1][0];//<

Camera.m[0][2] = World.m[2][0];//<

Camera.m[0][3] = 0.0f;

Camera.m[1][0] = World.m[0][1];//<

Camera.m[1][1] = World.m[1][1];
Camera.m[1][2] = World.m[2][1];//<

Camera.m[1][3] = 0.0f;

Camera.m[2][0] = World.m[0][2];//<

Camera.m[2][1] = World.m[1][2];//<

Camera.m[2][2] = World.m[2][2];
Camera.m[2][3] = 0.0f;
////////////////////////////////////////////////

// calc new position

Camera.m[3][0] = -((Camera.m[0][0]*World.m[i].X) + (Camera.m[1][0]*World.m[i].Y) + (Camera.m[2][0]*World.m[i].Z));
Camera.m[3][1] = -((Camera.m[0][1]*World.m[i].X) + (Camera.m[1][1]*World.m[i].Y) + (Camera.m[2][1]*World.m[i].Z));
Camera.m[3][2] = -((Camera.m[0][2]*World.m[i].X) + (Camera.m[1][2]*World.m[i].Y) + (Camera.m[2][2]*World.m[i].Z));
Camera.m[3][3] = 1.0f;



hope this helps
u0_80
u0_80
unshaven bastard - do you have any code as an example?

or anyone?
u0_80
u0_80
any more help?

- still can''t figure out the correct code..if you can help, thanks!
u0_80
u0_80
last chance!! ??

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.