Code:
#include "cam.h"
#include <math.h>
void
GLTK_Cam_GetTransform(GLTK_Cam* camera, GLTK_Mtx m)
{
m[0] = camera->uAxis[0];
m[1] = camera->vAxis[0];
m[2] = -camera->nAxis[0];
m[3] = 0.0;
m[4] = camera->uAxis[1];
m[5] = camera->vAxis[1];
m[6] = -camera->nAxis[1];
m[7] = 0.0;
m[8] = camera->uAxis[2];
m[9] = camera->vAxis[2];
m[10] = -camera->nAxis[2];
m[11] = 0.0;
m[12] = -GLTK_Vec_Dot(camera->uAxis, camera->pos);
m[13] = -GLTK_Vec_Dot(camera->vAxis, camera->pos);
m[14] = GLTK_Vec_Dot(camera->nAxis, camera->pos);
m[15] = 1.0;
}
void
GLTK_Cam_Init(GLTK_Cam* camera)
{
GLTK_Vec_Set(camera->uAxis, 1.0, 0.0, 0.0, 1.0);
GLTK_Vec_Set(camera->vAxis, 0.0, 1.0, 0.0, 1.0);
GLTK_Vec_Set(camera->nAxis, 0.0, 0.0, -1.0, 1.0);
GLTK_Vec_Set(camera->pos, 0.0, 0.0, 0.0, 1.0);
}
void
GLTK_Cam_LookAt(GLTK_Cam* camera,
GLTK_Vec location,
GLTK_Vec target,
GLTK_Vec up)
{
GLTK_Vec_Dup(camera->pos, location);
GLTK_Vec_Dup(camera->nAxis, target);
GLTK_Vec_Subv(camera->nAxis, location);
GLTK_Vec_Normalize(camera->nAxis);
GLTK_Vec_Normalize(up);
GLTK_Vec_Dup(camera->uAxis, camera->nAxis);
GLTK_Vec_Cross(camera->uAxis, up);
GLTK_Vec_Normalize(camera->uAxis);
GLTK_Vec_Dup(camera->vAxis, camera->uAxis);
GLTK_Vec_Cross(camera->vAxis, camera->nAxis);
}
#if 0
void
GLTK_Cam_LookAt(GLTK_Cam* camera,
GLTK_Vec location,
GLTK_Vec target,
GLTK_Vec up)
{
GLTK_Vec_Dup(camera->pos, location);
GLTK_Vec_Dup(camera->nAxis, location);
GLTK_Vec_Sub(camera->nAxis, target);
GLTK_Vec_Normalize(camera->nAxis);
GLTK_Vec_Normalize(up);
GLTK_Vec_Dup(camera->uAxis, camera->nAxis);
GLTK_Vec_Cross(camera->uAxis, up);
GLTK_Vec_Normalize(camera->uAxis);
GLTK_Vec_Dup(camera->vAxis, camera->uAxis);
GLTK_Vec_Cross(camera->vAxis, camera->nAxis);
}
#endif
void
GLTK_Cam_Yaw(GLTK_Cam* camera, float angle)
{
GLTK_Mtx r;
GLTK_Mtx_SetToIdentity(r);
GLTK_Vec_Normalize(camera->vAxis);
GLTK_Mtx_Rotate(r, -angle, camera->vAxis);
GLTK_Mtx_Mulv(r, camera->nAxis);
GLTK_Vec_Normalize(camera->nAxis);
GLTK_Vec_Dup(camera->uAxis, camera->nAxis);
GLTK_Vec_Cross(camera->uAxis, camera->vAxis);
GLTK_Vec_Normalize(camera->uAxis);
}
void
GLTK_Cam_Pitch(GLTK_Cam* camera, float angle)
{
GLTK_Mtx r;
GLTK_Mtx_SetToIdentity(r);
GLTK_Vec_Normalize(camera->uAxis);
GLTK_Mtx_Rotate(r, -angle, camera->uAxis);
GLTK_Mtx_Mulv(r, camera->nAxis);
GLTK_Vec_Normalize(camera->nAxis);
GLTK_Vec_Dup(camera->vAxis, camera->uAxis);
GLTK_Vec_Cross(camera->vAxis, camera->nAxis);
GLTK_Vec_Normalize(camera->vAxis);
}
void
GLTK_Cam_Roll(GLTK_Cam* camera, float angle)
{
GLTK_Mtx r;
GLTK_Mtx_SetToIdentity(r);
GLTK_Vec_Normalize(camera->nAxis);
GLTK_Mtx_Rotate(r, -angle, camera->nAxis);
GLTK_Mtx_Mulv(r, camera->vAxis);
GLTK_Vec_Normalize(camera->vAxis);
GLTK_Vec_Dup(camera->uAxis, camera->nAxis);
GLTK_Vec_Cross(camera->uAxis, camera->vAxis);
GLTK_Vec_Normalize(camera->uAxis);
}
void
GLTK_Cam_MoveForward(GLTK_Cam* camera, float distance)
{
GLTK_Vec moveVec;
GLTK_Vec_Dup(moveVec, camera->nAxis);
GLTK_Vec_Scale(moveVec, distance);
GLTK_Vec_Addv(camera->pos, moveVec);
}
void
GLTK_Cam_MoveUp(GLTK_Cam* camera, float distance)
{
GLTK_Vec moveVec;
GLTK_Vec_Dup(moveVec, camera->vAxis);
GLTK_Vec_Scale(moveVec, distance);
GLTK_Vec_Addv(camera->pos, moveVec);
}
void
GLTK_Cam_MoveRight(GLTK_Cam* camera, float distance)
{
GLTK_Vec moveVec;
GLTK_Vec_Dup(moveVec, camera->uAxis);
GLTK_Vec_Scale(moveVec, distance);
GLTK_Vec_Addv(camera->pos, moveVec);
}
By the way, I would ignore quaternions and euler angles; they are both more difficult (IMO) to understand than the Linear Algebra approach (this one).