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

1 Answer 1

1
\$\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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .