Jump to content
  • Advertisement
Sign in to follow this  

matrix camera theory

This topic is 5393 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a matrix-based camera. I'm new to this type of (non-OGL-based) camera - is my code right? I'm using mtxlib (from GPG1) for linear algebra operations. Also, I'm wondering how I can input this camera state to OGL - is there a better way than calculatiog the vectors for gluLookAt()?
bool Camera::init()
    localToWorld=IdentityMatrix44(); //world origin, no rotation
	forward  =  vector3(0,0,1);
	right    =  vector3(1,0,0);
	up       =  vector3(0,1,0);
    return true;
bool Camera::tick()
    localToWorld= rotation * translation * localToWorld;
    up     =vector3(localToWorld[0][1],localToWorld[1][1],localToWorld[2][1]);
    right  =vector3(localToWorld[0][0],localToWorld[1][0],localToWorld[2][0]);

    return true;
Camera::~Camera() {}

void Camera::move(vector3 d) //d=displacement
{ translation=translation*TranslateMatrix44(d.x, d.y, d.z); }

void Camera::pitch(float rad)
{ rotation = rotation * RotateRadMatrix44('x', rad); }

void Camera::yaw(float rad)
{ rotation = rotation * RotateRadMatrix44('y', rad); }

void Camera::roll(float rad)
{ rotation = rotation * RotateRadMatrix44('z', rad); }

edit: updated the code to current condition [Edited by - thedustbustr on October 14, 2004 1:06:50 AM]

Share this post

Link to post
Share on other sites
Some comments:

1) What are you doing with the localToWorld variable? It seems to just be the identity matrix for all time

2) If the translation variable is a vector, there is no need to multiply by a translation matrix. Just do this, which is cheaper:

translation = translation + d;

3) You're defining pitch to be rotation about x, yaw as rotation about y, roll as rotation about z. The axes about which these things are defined are not universal---there are other interpretations. But, your choices are okay. See docs on rotations at Magic Software for a comprehensive discussion.

4) You can load your matrix directly into OpenGL using glLoadMatrix, with matrix mode set to GL_MODELVIEW. This takes an array of 16 floats that contains the values in your 4x4 transformation matrix. You've listed translation and rotation separately in your code. I'm assuming translation is a vector3 and rotation is a matrix3x3 (sorry, not familiar with mtxlib object names). If my assumption is true, you'd have to stuff translation and rotation into a single float[4][4] array. The way you place the values in the array is is important. See the OpenGL Red Book chapter 3 for details:

OpenGL Red Book version 1

About 25% into the chapter you'll see a definition for transformation matrix M. The entries m1 through m16 correspond to the entries in your float[4][4] array. The book describes the mapping. The rotation part goes in the upper-left 3x3 part of M. The translation vector goes in the first 3 rows of the last column. You may need to transpose rotation before stuffing it into the upper-left 3x3 corner, but otherwise you just stuff it as is.

Share this post

Link to post
Share on other sites
Also, you need to re-orthonormalize upperleft 3x3 part of your matrix time to time. (precision issue)

Can be done by, say,
Column1=normalized(Column2 cross Column3);
Column2=normalized(Column3 cross Column1);
where Column1, Column2, Column3 it's 3d vectors corresponding to columns in upperleft 3x3 matrix.

where normalized(A)=A/|A| where |A| is length of A
It's assuming convention that x^ = y^ cross z^ where ^ mean unit-length vector....

Share this post

Link to post
Share on other sites
update: all problems solved.

Ok I have the assert problem solved (minor precision issue). I also found a much better way to find the vectors (from GPG1) - see updated Camera::tick method. I'm still having issues with movement: after some rotation the forward vector and right vector are effectively switched. Why is this happening?

Dmytry, what time scale are we talking here- do I need to do this every frame?

Thanks. Dustin

edit:several additions to source and comments and more questions
edit2: updated source code in initial post, removed things i figured out
edit3:I have a demo put together with the relevant source but my host is down, i'll put it up tomorrow if someone is willing to look at it
edit4: figured it all out. thanks guys for the help :)

[Edited by - thedustbustr on October 14, 2004 10:25:49 AM]

Share this post

Link to post
Share on other sites

Dmytry, what time scale are we talking here- do I need to do this every frame?

Don't really know. Depends.

In fact you don't really need to do it at every frame(maybe, even every 100th frame will do, maybe even 1000), but it's not THAT slow and i would do it at every frame if camera has been modified, for simplicity and to be sure. Why it's should be done only if camera was modified : otherwise camera *might* very slowly drift due to inprecision caused by re-orthonormalization itself...

If your camera class is made using get/set , you can make a counter that is decremented by each "set" and when it's <0 , matrix is re-orthonormalized and counter is set to, say, 100 .

I just use quaternions for camera. It's simpler once you have quaternion class. Quaternions can be multiplied in exactly same way as rotation matrices, and easily converted to rotation matrix when needed. So once you have quaternion class/struct, it's almost the same. Both quaternion and matrices is a transforms.

In fact, auto-orthonormalizing matrix works exactly as quaternion except that it is more complicated than quaternion.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!