After figuring out the answer to my previous question I have found the cause to be some kind of mathematical oddity.
Using the GLM (OpenGL) library I create an orientation as follows
glm::gtx::quaternion::orientation =
glm::gtx::quaternion::angleAxis(pitchAccum, 1.0f, 0.0f, 0.0f) *
glm::gtx::quaternion::angleAxis(yawAccum, 0.0f, 1.0f, 0.0f);
Now if I create a matrix from this orientation it is no longer column major but somehow becomes row major
glm::mat4 view = glm::gtx::quaternion::toMat4(orientation);
In other words the 3 coordinates axes are found by accessing the matrix using row major indices
view[0][0], view[1][0], view[2][0] // X axis
view[0][1], view[1][1], view[2][1] // Y axis
view[0][2], view[1][2], view[2][2] // Z axis
In other words the transpose of the rotation part.
The translation part of the matrix should still be set using column major in order for the final view matrix to work as intended.
view[3][0] = -glm::dot(glm::vec3(view[0][0], view[1][0], view[2][0]), position); // Right
view[3][1] = -glm::dot(glm::vec3(view[0][1], view[1][1], view[2][1]), position); // Up
view[3][2] = -glm::dot(glm::vec3(view[0][2], view[1][2], view[2][2]), position); // Forward
Why is the rotation matrix flipped from column major to row major (transposed?) when using the orientation?
EDIT:
// Move forward
if (glfwGetKey('W') == GLFW_PRESS)
{
//movement += glm::vec3(view[2][0], view[2][1], view[2][2]); // incorrect
movement += -glm::vec3(view[0][2], view[1][2], view[2][2]); // correct
}
// Move backward
if (glfwGetKey('S') == GLFW_PRESS)
{
//movement += -glm::vec3(view[2][0], view[2][1], view[2][2]); // incorrect
movement += glm::vec3(view[0][2], view[1][2], view[2][2]); // correct
}
// Strafe left
if (glfwGetKey('A') == GLFW_PRESS)
{
//movement += -glm::vec3(view[0][0], view[0][1], view[0][2]); // incorrect
movement += -glm::vec3(view[0][0], view[1][0], view[2][0]); // correct
}
// Strafe right
if (glfwGetKey('D') == GLFW_PRESS)
{
//movement += glm::vec3(view[0][0], view[0][1], view[0][2]); // incorrect
movement += glm::vec3(view[0][0], view[1][0], view[2][0]); // correct
}