4
\$\begingroup\$

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?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Feb 1, 2015 at 6:10

3 Answers 3

1
\$\begingroup\$

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}$$

\$\endgroup\$
0
\$\begingroup\$

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; viewMatrix = XMLoadFloat4x4(&f_view); 

You need to multiply the translation vector by the rotation first

\$\endgroup\$
0
\$\begingroup\$

Another way to do it, if you already have the quaternion-rotation of a vector:

x = q.rotate (1,0,0) y = q.rotate (0,1,0) z = crossprod(x,y) matrix = { x,y,z,p }; 

It's definitely not the fastest way to do it. But it's one that is easy to understand.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.