I have a simple scenario. I have a simple scene, and in it I'm drawing a grid and a model, with some axis for orientation.
I noticed when I rotate the model about it's local Y axis, if I rotate the model clockwise, the vertices end up rendering as if they've been rotated counterclockwise. I can see this by rendering the model's local forward vector.
Here's a picture of what I mean. Initially, the world forward, local forward, and model all face the same direction.
However, after I begin rotating the object clockwise, I notice the "world forward vector" is rotating clockwise, but my model rotates counterclockwise?
When I export the model from Blender3D I use the coordinate system "Forward: -Z" and "UP: Y Up", which matches the RHS coordinate system I'm using in opengl.
When I "rotate the object", I mean I multiply the object's rotation matrix like so:
float constexpr angle = 1.0f;
glm::vec3 const axis = glm::vec3{0.0, 1.0, 0.0};
object.rotation = glm::angleAxis(glm::radians(angle), axis) * object.rotation;
Here's my vertex shader, I'm just multiplying the vertices by the MVP matrix.
vertex shader:
in vec4 a_position;
in vec4 a_color;
out vec4 v_color;
uniform mat4 u_mvpmatrix;
void main()
{
gl_Position = u_mvpmatrix * a_position;
v_color = a_color;
}
The rotation object.rotation 's initial value is the quaternion identity. Here's how I calculate the MVP matrix uniform value:
glm::mat4 const tmatrix = glm::translate(glm::mat4{}, this->translation);
glm::mat4 const rmatrix = glm::toMat4(this->rotation);
glm::mat4 const smatrix = glm::scale(glm::mat4{}, this->scale);
glm::mat4 const model_matrix = tmatrix * rmatrix * smatrix;
// camera_xyz are world-coords for the camera
// target_xyz is world-coords of the object
glm::vec3 const UP = glm::vec3{0.0f, 1.0f, 0.0f};
glm::mat4 const view = glm::lookAt(camera_xyz, target_xyz, UP);
glm::mat4 const projection = glm::perspective(fov, aspect_ratio, near, far);
glm::mat4 const mvp_matrix = projection * view * model_matrix;
Other relavent calculations:
glm::vec3 eye_forward() const { return forward_; }
glm::vec3 eye_up() const { return up_; }
glm::vec3 eye_backward() const { return -eye_forward(); }
glm::vec3 eye_left() const { return -eye_right(); }
glm::vec3 eye_right() const { return glm::normalize(glm::cross(eye_forward(), eye_up())); }
glm::vec3 eye_down() const { return -eye_up(); }
glm::vec3 world_forward() const { return forward_ * orientation(); }
glm::vec3 world_up() const { return up_ * orientation(); }
glm::vec3 world_backward() const { return -world_forward(); }
glm::vec3 world_left() const { return -world_right(); }
glm::vec3 world_right() const { return glm::normalize(glm::cross(world_forward(), world_up())); }
glm::vec3 world_down() const { return -world_up(); }
From what I can tell, it seems like I'm doing everything right. Can someone explain it to me? I also have a video showing this in more detail. This is important, because I move the object "forward" based on it's forward vector, so when I rotate the object and move it "forward" it's not moving in the direction it is facing.
edit: Am I calculating the "local forward" correctly with this calculation?
double edit: I just noticed I labeled the "World" and "Object space" vectors backwards. The green arrow is the World forward vector (0, 0, -1) and the light blue is the object's local forward vector.
// forward_ is initialized with -Z (0.0, 0.0, -1.0)
glm::vec3 world_forward() const { return forward_ * orientation();
glm::quat const& orientation() const { return object.rotation; }
orientation()
, and what is the value ofobject.rotation
before the transform? \$\endgroup\$orientation()
returns object.rotation.object.rotation
's initial value is the identity Quaternion. \$\endgroup\$