# Please verify my vector/look-at matrix code

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

## Recommended Posts

Hello all. Im trying to create a left handed look-at matrix. Im using the way described in the dx9 sdk docs for the D3DXMatrixLookAtLH function. I did it using D3DXVECTOR3 and D3DXMATRIX manually as in the docs and it worked, however for some reason its not working with my own vector and matrix classes. I seem to be loosing precision after normalizing, D3DX vectors get 0.999947 ( something like that ) and I get 1.0. Here's how im constructing the LH look-at matrix:
/* Creates a look-at matrix */
inline void matrix4_make_lookat( vector3<T> view, vector3<T> position, vector3<T> up )
{
vector3<T> zaxis( view - position );
zaxis.vector3_normalize();
vector3<T> xaxis;
xaxis.vector3_cross_product( up, zaxis );
vector3<T> yaxis;
yaxis.vector3_cross_product( zaxis, xaxis );

_11 = xaxis.v_x;
_12 = yaxis.v_x;
_13 = zaxis.v_x;
_14 = 0;

_21 = xaxis.v_y;
_22 = yaxis.v_y;
_23 = zaxis.v_y;
_24 = 0;

_31 = xaxis.v_z;
_32 =  yaxis.v_z;
_33 =  zaxis.v_z;
_34 = 0;

_41 = -xaxis.vector3_dot_product( position );
_42 = -yaxis.vector3_dot_product( position );
_43 = -zaxis.vector3_dot_product( position );
_44 = 1;
}


Here's my vector templated class:
template <class T> class vector3
{
public:
/* Constructor ( default ) */
vector3() :
x(0), y(0), z(0)
{
}

/* Constructor ( overloaded ) Incoming vector values */
vector3( T tx, T ty, T tz ) :
x(tx), y(ty), z(tz)
{
}

/* Constructor ( overloaded ) Incoming vector3 class instance */
vector3( vector3 &vec3 ) :
x(vec3.x), y( vec3.y ), z( vec3.z )
{
}

inline vector3 &operator =( const vector3 &vec3 )
{
x = vec3.x,
y = vec3.y,
z = vec3.z;

return *this;
}

inline vector3 operator +( const vector3 &vec3 )
{
return vector3( x + vec3.x, y + vec3.y, z + vec3.z );
}

inline vector3 operator -( const vector3 &vec3 )
{
return vector3( x - vec3.x, y - vec3.y, z - vec3.z );
}

/* Overload multiplication operator ( multiply by type ) */
inline vector3 operator *( T t )
{
return vector3( x * t, y * t, z *t );
}

inline vector3  &operator +=( const vector3 &vec3 )
{
x += vec3.x;
y += vec3.y;
z += vec3.z;

return *this;
}

inline vector3 &operator -= ( const vector3 &vec3 )
{
x -= vec3.x;
y -= vec3.y;
z -= vec3.z;

return *this;
}

/* Cross Product */
inline void vector3_cross_product( vector3 &vec3_1, vector3 &vec3_2 )
{
x = vec3_1.y * vec3_2.z - vec3_1.z * vec3_2.y;
y = vec3_1.z * vec3_2.x - vec3_1.x * vec3_2.z;
z = vec3_1.x * vec3_2.y - vec3_1.y * vec3_2.x;
}

/* Dot Product */
inline T vector3_dot_product( vector3 &vec3 )
{
return x * vec3.x + y * vec3.y + z * vec3.z ;
}

/* Divide by Scalar */
inline vector3 vector3_divide_by_scalar( T scalar )
{
return vector3( x / scalar, y / scalar, z / scalar );
}

/* Vector invert */
inline void vector3_invert( void )
{
x = -x,
y = -y,
z = -z;
}

/* Get vector length */
inline T vector3_length( void )
{
return sqrt( x * x + y * y + z * z );
}

/* Normalize vector */
inline void vector3_normalize( void )
{
T length = vector3_length();

x /= length;
y /= length;
z /= length;
}

/* Set the vector's values */
inline void vector3_set( T tx, T ty, T tz )
{
x = tx;
y = ty;
z = tz;
}

/* 3D Vector values */
T x, y, z;

};


Please tell me if im doing anything wrong anywhere. :( Thanks

##### Share on other sites
Maybe you are doing nothing wrong, 0.999947 is practically 1.0.
You get impreciseness as soon as you start calculating with floats already, so if it's 1.0 or 0.999... at the beginning doesn't matter.
But maybe I am wrong...

Constantin

##### Share on other sites
At first glance your vector class looks fine, and the lookat function looks correct as well. To me at least the error you describe seems within reasonable limits.

##### Share on other sites

Dude I have even tried with double's and get the same thing

[crying]

##### Share on other sites
Does the 0.000053 difference lead to a wrong calculated lookat matrix, or are your only guessing that your vector class is wrong because of the difference?

As jyk pointed out: your vector class seems fine! so if you get a wrong lookat-matrix you should search a mistake in the lookat-function.

Constantin

##### Share on other sites

Dammit, I feel so stupid! I was passing the wrong vectors when creating the look-at matrix. Position for view, and View for position.

Stupid me!

Thank you for your help though guys.

One more question though. If I was to create the look-at matrix for use in OpenGL ( uses a right hand coordinate system right? ) what would I need to do?

Im not that math savvy, hence me trying to create my own look-at matrix to get a more in depth understanding of it all.

Thank you, and I am sorry for wasting your time for my stupid ( very stupid! ) mistake.

##### Share on other sites
Quote:
 One more question though. If I was to create the look-at matrix for use in OpenGL ( uses a right hand coordinate system right? ) what would I need to do?
For OpenGL there are a couple of things to take into account. Starting with the standard algorithm (which is what you have):

Vector3 z = normalize(target-pos);
Vector3 x = normalize(up.Cross(z));
Vector3 y = z.Cross(x);

float tx = -pos.Dot(x);
float ty = -pos.Dot(y);
float tz = -pos.Dot(z);

We now need to load this into an OpenGL-style (column vector) matrix:

[xx xy xz tx]
[yx yy yz ty]
[zx zy zz tz]
[0 0 0 1 ]

Remember that OpenGL is column-major, so this becomes:

m[0] = xx; m[4] = xy; m[8] = xz; m[12] = tx;
m[1] = yx; m[5] = yy; m[9] = yz; m[13] = ty;
m[2] = zx; m[6] = zy; m[10] = zz; m[14] = tz;
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;

This creates a camera space with +z forward. For OpenGL we need -z forward, so as a last step we apply a 180-degree rotation about the y axis. To cut to the chase, replacing the line:

Vector3 z = normalize(target-pos);

With:

Vector3 z = normalize(pos-target);

Will do exactly that.

(I can't absolutely guarantee the correctness of the above, but this is how I've implemented it in my own matrix class, and the results appear to match those of gluLookAt().)

##### Share on other sites
Thank you jyk, I shall implement and try it out soon.

Thanks Alot!

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11