 # gluLookAt

How can I implement my own version of the gluLookAt() function: If I have the desired direction and up vector, how do i calculate the corresponding rotation matrix?

And no, I don’t want to use gluLookAt(). I want to learn how to do it myself taken from DirectX sdk:

HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
D3DVECTOR& vAt, D3DVECTOR& vWorldUp )
{
// Get the z basis vector, which points straight ahead. This is the
// difference from the eyepoint to the lookat point.
D3DVECTOR vView = vAt - vFrom;

``````FLOAT fLength = Magnitude( vView );
if( fLength &lt; 1e-6f )
``````

return E_INVALIDARG;

``````// Normalize the z basis vector
vView /= fLength;

// Get the dot product, and calculate the projection of the z basis
// vector onto the up vector. The projection is the y basis vector.
FLOAT fDotProduct = DotProduct( vWorldUp, vView );

D3DVECTOR vUp = vWorldUp - fDotProduct * vView;

// If this vector has near-zero length because the input specified a
// bogus up vector, let's try a default up vector
if( 1e-6f &gt; ( fLength = Magnitude( vUp ) ) )
{
``````

vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView;

// If we still have near-zero length, resort to a different axis.
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
{
vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView;

``````if( 1e-6f &gt; ( fLength = Magnitude( vUp ) ) )
``````

return E_INVALIDARG;
}
}

``````// Normalize the y basis vector
vUp /= fLength;

// The x basis vector is found simply with the cross product of the y
// and z basis vectors
D3DVECTOR vRight = CrossProduct( vUp, vView );

// Start building the matrix. The first three rows contains the basis
// vectors used to rotate the view to point at the lookat point
D3DUtil_SetIdentityMatrix( mat );
mat._11 = vRight.x;    mat._12 = vUp.x;    mat._13 = vView.x;
mat._21 = vRight.y;    mat._22 = vUp.y;    mat._23 = vView.y;
mat._31 = vRight.z;    mat._32 = vUp.z;    mat._33 = vView.z;

// Do the translation values (rotations are still about the eyepoint)
mat._41 = - DotProduct( vFrom, vRight );
mat._42 = - DotProduct( vFrom, vUp );
mat._43 = - DotProduct( vFrom, vView );

return S_OK;
``````

}

they use a right-handed coordinate system, you might have to change some signs

[This message has been edited by Gorg (edited 08-03-2000).]