camera lookat

Started by
4 comments, last by Evil Steve 15 years, 3 months ago
I have written a camera look at method, which simply creates a view matrix from a direction vector. It looks like this for those interested:

Matrix createViewMatrix(Vector viewDirection) {
	Vector zAxis = viewDirection.getNormalized();
	Vector xAxis = Vector.cross(zAxis, Vector.up)
	Vector yAxis = Vector.cross(xAxis, zAxis);

	Matrix viewMatrix = new Matrix();
	viewMatrix[0] = xAxis.x; viewMatrix[1] = xAxis.y; viewMatrix[ 2] = xAxis.z;
	viewMatrix[4] = yAxis.x; viewMatrix[5] = yAxis.y; viewMatrix[ 6] = yAxis.z;
	viewMatrix[8] = zAxis.x; viewMatrix[9] = zAxis.y; viewMatrix[10] = zAxis.z;

	return viewMatrix;
}


As you can see the method only cares about which direction you want to look at. The problem I have, is that I'm not sure what to do, in cases where you're looking down or up, because then the up-vector will cancel out the direction vector. Since up and direction will be the same.. For example, if I pass this vector to the method: createViewMatrix(new Vector(0.0f, 1.0f, 0.0f)); The up vector and direction vector will be the same, and since they're not perpendicular, the cross product will fail.. and the whole thing will end up with a bad matrix.. I have some uhm.. ideas of how to solve this, but I think they're mostly stupid hacks which will eventually blow up in my face some time in the future.. So are there any "correct" ways to solve this without forcing the user to specify an up-vector?
Advertisement
Quote:Original post by randomuser
I have written a camera look at method, which simply creates a view matrix from a direction vector. It looks like this for those interested:
*** Source Snippet Removed ***

As you can see the method only cares about which direction you want to look at.
The problem I have, is that I'm not sure what to do, in cases where you're looking down or up, because then the up-vector will cancel out the direction vector. Since up and direction will be the same..

For example, if I pass this vector to the method:
createViewMatrix(new Vector(0.0f, 1.0f, 0.0f));

The up vector and direction vector will be the same, and since they're not perpendicular, the cross product will fail.. and the whole thing will end up with a bad matrix..

I have some uhm.. ideas of how to solve this, but I think they're mostly stupid hacks which will eventually blow up in my face some time in the future.. So are there any "correct" ways to solve this without forcing the user to specify an up-vector?
Not really. You could check if the vector is pointing up/down or almost up/down (A dot product would probably be quickest). This is why every other function like this takes an up vector. Also, what do you intend to do if you ever need to roll the view along the Z axis? I.e. what if you want to roll right by 45 degrees? You'll need an up vector then.
Quote:Original post by Evil Steve
Not really. You could check if the vector is pointing up/down or almost up/down (A dot product would probably be quickest). This is why every other function like this takes an up vector. Also, what do you intend to do if you ever need to roll the view along the Z axis? I.e. what if you want to roll right by 45 degrees? You'll need an up vector then.


I'm not to keen(actually pretty darn clueless) on quaternions.. But is it possible to solve this internally(inside the method) with quaternions, or some other super-advanced crazy math?

Quote:Original post by randomuser
Quote:Original post by Evil Steve
Not really. You could check if the vector is pointing up/down or almost up/down (A dot product would probably be quickest). This is why every other function like this takes an up vector. Also, what do you intend to do if you ever need to roll the view along the Z axis? I.e. what if you want to roll right by 45 degrees? You'll need an up vector then.


I'm not to keen(actually pretty darn clueless) on quaternions.. But is it possible to solve this internally(inside the method) with quaternions, or some other super-advanced crazy math?
Nope. To describe a direction in 3D space, you need 2 vectors (The third can be determined from the cross product of the two). What you're doing is the equivalent of trying to describe a 2D line with a single point - there's an infinite number of lines that pass through that one point, the same goes for 3D - there's an infinite number of possible matrices with the same direction vector.
Quote:Original post by Evil Steve
Quote:Original post by randomuser
Quote:Original post by Evil Steve
Not really. You could check if the vector is pointing up/down or almost up/down (A dot product would probably be quickest). This is why every other function like this takes an up vector. Also, what do you intend to do if you ever need to roll the view along the Z axis? I.e. what if you want to roll right by 45 degrees? You'll need an up vector then.


I'm not to keen(actually pretty darn clueless) on quaternions.. But is it possible to solve this internally(inside the method) with quaternions, or some other super-advanced crazy math?
Nope. To describe a direction in 3D space, you need 2 vectors (The third can be determined from the cross product of the two). What you're doing is the equivalent of trying to describe a 2D line with a single point - there's an infinite number of lines that pass through that one point, the same goes for 3D - there's an infinite number of possible matrices with the same direction vector.


Ahh.. why is nothing ever simple? :(

Oh well, guess I have to surrender to the almighty math of 3d and add a damn up-vector argument! bawhaha..

Thanks for your help!
Quote:Original post by randomuser
Ahh.. why is nothing ever simple? :(

Oh well, guess I have to surrender to the almighty math of 3d and add a damn up-vector argument! bawhaha..

Thanks for your help!
You can always make it a default argument. For instance, my code looks like:
Matrix& Matrix::CreateLookAt(const Vec3& vPos, const Vec3& vDir, const Vec3& vUp=Vec3(0, 1, 0));

This topic is closed to new replies.

Advertisement