# How do I create a view matrix directly from a quaternion and a position vector?

Given a quaternionic camera such that:

typedef struct
{
vector3 upReference;
vector3 rightReference;
vector3 forwardReference;

vector3 position;
quaternion orientation;

float pov;
} camera_t;


Where:

• upReference, rightReference, forwardReference are always (0,1,0, 1,0,0, 0,0,-1) respectively
• pov is the viewing angle

and quaternion is:

typedef struct
{
float x, y, z, w;
} quaternion;


Is there some way to create a view matrix directly from all of this and skip gluLookAt?

• Since I would first have to mentally parse it in order to write a complete answer, I'll just note that Wikpedia has section for this entitled Quaternion-derived Rotation Matrix, which you could use to create the rotation component of a view matrix. The translation would have to applied separately, because the quaternions rotate vectors around an assumed origin. Feb 1, 2015 at 6:10

The three columns of a 3x3 rotation matrix (or the upper 3x3 block of a 4x4 rotation-and-translation matrix) can be thought of as the images of unit vectors in the x+, y+, and z+ directions, respectively, after rotation.

That means we can find the first column by rotating the vector $$\(1, 0, 0)\$$ by the quaternion $$\q\$$:

\begin{align} q (1i + 0j + 0k + 0) q^{-1} &= (q_xi + q_yj + q_zk + q_w) (i) (-q_xi - q_yj - q_zk + q_w)\\ & = (q_x^2 - q_y^2 -q_z^2 + q_w^2)i + 2(q_xq_y + 2q_zq_w)j + 2(q_xq_z - 2q_yq_w)k\\ \end{align}

And we can repeat this for each of the other columns, and use the fact that $$\\|q\| = 1\$$ to simplify the terms with the squares into the equivalent $$\q_x^2 - q_y^2 -q_z^2 + q_w^2 = 1 - 2(q_y^2 + q_z^2)\$$ and similar for the other axes. That gives us this 3x3 rotation matrix $$\R\$$ that does the same job as the quaternion $$\q\$$:

$$R = 2 \begin{bmatrix} \frac 1 2 - q_y^2 - q_z^2 & q_xq_y -q_zq_w & q_xq_z + q_yq_w\\ q_xq_y +q_zq_w & \frac 1 2 - q_x^2 - q_z^2 & q_yq_z -q_xq_w\\ q_xq_z -q_yq_w & q_yq_z + q_xq_w & \frac 1 2 - q_x^2 - q_y^2 \end{bmatrix}$$

But of course for a view matrix, we want the inverse of this rotation. But for a pure rotation matrix where all columns are orthogonal unit vectors, that's just the transpose:

$$R^T = 2 \begin{bmatrix} \frac 1 2 - q_y^2 - q_z^2 & q_xq_y +q_zq_w & q_xq_z - q_yq_w\\ q_xq_y - q_zq_w & \frac 1 2 - q_x^2 - q_z^2 & q_yq_z +q_xq_w\\ q_xq_z + q_yq_w & q_yq_z - q_xq_w & \frac 1 2 - q_x^2 - q_y^2 \end{bmatrix}$$

Now to translate this back so that some position vector $$\\vec p = (p_x, p_y, p_z)\$$ gets mapped to the origin, we can take the image of $$\\vec p\$$ after rotation by $$\R^T\$$:

$$\vec p^\prime = R^T \vec p = 2\begin{bmatrix} p_x(\frac 1 2 - q_y^2 - q_z^2) + p_y(q_xq_y + q_zq_w) + p_z(q_xq_z - q_yq_w)\\ p_x(q_xq_y - q_zq_w) + p_y(\frac 1 2 - q_x^2 - q_z^2) + p_z(q_yq_z +q_xq_w)\\ p_x(q_xq_z + q_yq_w) + p_y(q_yq_z - q_xq_w) + p_z(\frac 1 2 - q_x^2 - q_y^2) \end{bmatrix}$$

And subtract it to get the fourth column of our 4x4 view matrix $$\V\$$:

$$V = \begin{bmatrix}R^T &-\vec p^\prime\\ 0 \, 0 \, 0 & 1\end{bmatrix}$$

Try this below:

XMMATRIX is transpose of the transform matrix, so you read it as column,row

XMMATRIX viewMatrix = XMMatrixRotationQuaternion(v_quaterion);
XMFLOAT4X4 f_view;
XMStoreFloat4x4(&f_view, viewMatrix);
f_view._41 = mPosition.x * f_view._11 + mPosition.y * f_view._21 + mPosition.x * f_view._31;
f_view._42 = mPosition.x * f_view._12 + mPosition.y * f_view._22 + mPosition.x * f_view._32;
f_view._43 = mPosition.x * f_view._13 + mPosition.y * f_view._23 + mPosition.x * f_view._33;

x = q.rotate (1,0,0)