• Advertisement

Archived

This topic is now archived and is closed to further replies.

Regenerating camera vectors

This topic is 5928 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

Hi all, I am on page 671 of "The Zen of Direct3D games programming" and I am having troubles with understanding the regenerating the camera vectors. For the benefits of those who did not have the book, here it goes: * A camera''s position can be set by multipying martices against it right vector, look-at vector and up-vector (if I don''t get it wrong). * After a while, due to the limitations of floating point precision, the angle will be off - the angle between the Look At vector and right vector will not be 90 degrees. * To adjust the vectors such that it will be correct, here are the steps: Normalise the look-at vector Set the right vector = the cross product of the up and look-at vector Normalise the right vector Set the up vector = the cross product of the look-at and right vector Normalise the up vector Just to sum up - how does this works? Graphical representations will be great (but I am asking too much, I know). Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Cameras need to be cleaned periodically. Lenses get dirty, and so forth. You must maintain your fine equipment.

A snippet of my code, as an example:

    
void camInit (float posX, float posY, float posZ,
float viewX, float viewY, float viewZ,
float upX, float upY, float upZ)
{
p3setf (posX, posY, posZ, camera->pos);
v3setf (viewX, viewY, viewZ, camera->view);
v3setf (upX, upY, upZ, camera->up);
v3crossv3ccwrhs (camera->up, camera->view, camera->left);

camClean ();
}

void camClean ()
{
/* renormalize view and up */
v3normm (camera->view);
v3normm (camera->up);

/* straighten left vector */
v3crossv3ccwrhs (camera->up, camera->view, camera->left);
v3normm (camera->left);

/* straighten up vector */

v3crossv3ccwrhs (camera->view, camera->left, camera->up);
v3normm (camera->up);

camera->use = 0;
}

void camForward (float step)
{
POINT3 V;

v3mulf (camera->view, step, V);
v3addv3m (camera->pos, V);
}

void camBack (float step)
{
POINT3 V;

v3mulf (camera->view, step, V);
v3subv3m (camera->pos, V);
}

void camLeft (float step)
{
POINT3 V;

v3mulf (camera->left, step, V);
v3addv3m (camera->pos, V);
}

void camRight (float step)
{
POINT3 V;

v3mulf (camera->left, step, V);
v3subv3m (camera->pos, V);
}

void camUp (float step)
{
POINT3 V;

v3mulf (camera->up, step, V);
v3addv3m (camera->pos, V);
}

void camDown (float step)
{
POINT3 V;

v3mulf (camera->up, step, V);
v3subv3m (camera->pos, V);
}

void camRoll (float angle)
{
MATRIX44 M;
VECTOR3 V;

M44rot (camera->view, degtorad (angle), M);
v3trans (camera->up, M, V);
v3copv3 (V, camera->up);
v3trans (camera->left, M, V);
v3copv3 (V, camera->left);

if (++camera->use > 20)
camClean ();
}

void camPitch (float angle)
{
MATRIX44 M;
VECTOR3 V;

M44rot (camera->left, degtorad (angle), M);
v3trans (camera->view, M, V);
v3copv3 (V, camera->view);
v3trans (camera->up, M, V);
v3copv3 (V, camera->up);

if (++camera->use > 20)
camClean ();
}

void camYaw (float angle)
{
MATRIX44 M;
VECTOR3 V;

M44rot (camera->up, degtorad (angle), M);
v3trans (camera->view, M, V);
v3copv3 (V, camera->view);
v3trans (camera->left, M, V);
v3copv3 (V, camera->left);

if (++camera->use > 20)
camClean ();
}


___________________________________



Edited by - bishop_pass on February 1, 2002 11:04:59 AM

Share this post


Link to post
Share on other sites
Thanks for the code (It is much cleaner than that from Zen of Direct3D and better)...but I still have a question...

WHY does it work? This is the main crux of my question. Not how, but why...

Edited by - LonelyTower on February 1, 2002 12:27:04 PM

Share this post


Link to post
Share on other sites
The camera is represented as 3 orthogonal vectors and a position vector. If we continually rotate these vectors to move the camera (as we do) floating point error is introduced into the vectors so that you can't guarantee that they are still unit vectors or perpendicular to each other.

        
Y
/| |
|
| \
Z--------- X
/


There's a crude drawing of the XY plane with Z pointing outwards. That's our camera. The X and Y vectors define a plane. If we cross them, we can recalculate Z, making Z a 'clean' normal to X and Y. We normalize Z, making it a unit vector. If we renormalize Y, we now have a clean Y and Z vector defining a plane. If we cross those, we get a 'clean' normal X vector to that plane. Now, all we have to do is normalize X to make sure it is a unit vector.

___________________________________



Edited by - bishop_pass on February 1, 2002 12:30:16 PM

Share this post


Link to post
Share on other sites
Well, the source tag keeps mangling my picture, but I think you get the idea.

I have never seen the code in any of the 3d game books. Thanks for appreciating my code though!

___________________________________

Share this post


Link to post
Share on other sites

  • Advertisement