Raven July 23, 1999, 08:58 PM 

>>I checked your posting before I posted this. Well I didn't get that much out of it.. >>for example I'm not quite sure about the camera's point. I mean I have the point and >>the target.. do I build a new point before substracting or what? That is the first thing >>I have troubles with.. and the second is the yaw,pitch and roll. Well I know what they are >>and what they do etc. but I don't know how do I get them? >>Well this would be a good point to say that I'm trying to get camera from 3ds file and use it >>in my own engine u know =) >>I know I get the angles somehow doing some dot or cross products, but but.. >>Well I have a theory(based on one camera code) that I get the angles by doing those products >>between the camera and up vector, but I don't know what is the up vector etc. >> >>Hope you can help me more with this =) >>thanks anyway.. >> >>charly
Ok. You are trying to make a camera look at a point. You have a camera position vector and a target vector and you want the camera to sit at the position and to be rotated in such a way that it's "pointing" or "looking" at the target. Right so far? Ok then
I'm not sure about this i've never done a target based camera but this is how i'd do it(i just made this up). You can take up the idea and adjust it to your needs. Also, this is kinda long. Sorry:)
We've got 2 vectors:
Vp=(Xp, Yp, Zp) Vt=(Xt, Yt, Zt)
Vp is the position vector and Vt is the target vector(they are all vectors since we are talking linear algebra here, so we are in a vector space). Small note, i won't use matrices. They take too long to type. You can convert equations to matrices yourself
I'm assuming the camera has been translated to Vp already, however it's yaw, pitch and roll are 0. Therefore it essentially looks down z(righthanded coordinate system). Now, we build a vector Vc=(Xc, Yc, Zc) which represents the direction the camera is looking in(the up vector). If you have ignored yaw, pitch and roll(ie they are 0) then for a righthanded coordinate system(z increases out of the screen) we have:
Vc=(0,0,1)
Note this vector is normalized. Now, we have where the camera is looking and we have where it's supposed to look. We need to find the transformation that will make the dotproduct between Vc and Vt zero(ie the angle will be 0). With matrices we have:
Vc*Aij=Vt
You have to solve this for Aij(4x4 matrix). This means inverting Aij, taking Vc to be a column vector and Vt a row vector, a matrix product between them, and then your camera rotation matrix will be the inverse of Aij. Too long:) We'll use other methods instead. Lets try breaking up a complex 3D case into 2 simple 2D cases. We project Vc and Vt onto the XZ plane. We now have:
Vcp=(Xc, Zc) Vtp=(Xp, Zp)
Normalize them: Vcp=Vcp Vtp=Vtp After normalizing the dotproduct Vcp.Vtp is equal to cos(Theta) where Theta is the angle between the vectors. Needless to say that:
cos(Theta)=Vcp.Vtp => acos(Vcp.Vtp)=Theta
We got one angle. Back to 3D this angle is the rotation about the Yaxis since we projected onto the XZ plane. Rotate the vector Vc(the 3D camera vector) by it. Notice that now we can project it onto the XY plane. If we were to take the XY plane first then the length of Vcp for XY would be 0, since the X and Y components of it are 0! Now we can project it and do the same thing as with XZ. We have:
Vcp=(Xc, Yc) Vtp=(Xp, Yp)
Vcp=Vcp Vtp=Vtp
acos(Vcp.Vtp)=Theta'
Theta' is the rotation about the(you guessed it!) Zaxis. We can now compose the transformation by concatenating the matrices of rotation:
Aij and Bkl where Aij is rotation around Yaxis by Theta and Bkl is rotation around Zaxis by Theta'. Aij*Bkl=Cmn
NOTE!!! You HAVE to concatenate Aij*Bkl, NOT Bkl*Aij. This will be equivalent as taking the XY plane first in the notes above. As i said earlier the length of Vcp on XY is 0! Don't fool yourself by thinking that you already got the angle and the rotation is there. Notice that any rotation of the vector (0,0,1) around the Zaxis will ALWAYS return (0,0,1)!!!
Another NOTE!!! The actual camera matrix is Cmn^1(the inverse of Cmn). This is because if you will perform all this you will find yaw and roll. Pitch was not used in this, and i'm sure we can derive a theorem to say that at least one axis of rotation will not be used to transform this vector(ie we have an ambiguity along one axis, though this is not important). If you have yaw and roll the real matrix will be to rotate by yaw and roll! Hence the matrix to be used on the points in world coordinates is Cmn^1.
NOTE, the revenge!!! The order of concatenation is IMPORTANT!!! Don't forget that. That is the most common mistake about cameras(i did it, the other guy did it, EVERYBODY did it). First goes the translation of the camera from it's position to (0,0,0). Then go the rotations about the X, Y and Z axees(english???). THAT is the order it goes in, and NO OTHER! This might seem like overkill to say but so many people made the mistake you won't believe it.
This is kinda plump for realtime rendering so i would do everything on paper using nothing but the variables stated here and express Cmn in terms of the original Vt and Vp. This will be a matrix with formulas in it's cells. I would solve the formulas in realtime and get the numbers. All these normilzations and dotproducts might resolve themselves on paper to something simpler, though it's too long so i won't do it myself. Make sure you don't make a mistake though, or you're in for it. Or get a book where the matrix with the formulas is written down for you:)
Good luck,  Raven
P.S. If you got questions about the math used here email me, otherwise post a message
