3
\$\begingroup\$

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.

enter image description here

However, after I begin rotating the object clockwise, I notice the "world forward vector" is rotating clockwise, but my model rotates counterclockwise?

enter image description here

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; }
\$\endgroup\$
  • \$\begingroup\$ Two questions, what is orientation(), and what is the value of object.rotation before the transform? \$\endgroup\$ – Jay Jan 29 '18 at 7:40
  • \$\begingroup\$ Sorry, orientation() returns object.rotation. object.rotation 's initial value is the identity Quaternion. \$\endgroup\$ – Short Jan 29 '18 at 12:37
  • \$\begingroup\$ Ah, I see... I'm not too sure how quaternions are supposed to work here. \$\endgroup\$ – Jay Jan 29 '18 at 13:13
0
\$\begingroup\$

Using the righthand rule -- rotation about the y-axis with a positive angle will rotate your model counterclockwise in the x-z plane. That is how rotation is defined in opengl. You need a negative angle.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.