0
votes

So I'm working on a 3d painting application. I managed to make a basic renderer and model loader.

I created a camera system where I can use it to navigate around the scene(mouse/keyboard) but that's not what I want, so I made that camera static and now I'm trying to rotate/pan/zoom the model itself. I managed to implement panning and zooming. for panning i change the x/y position according to the mouse and for zooming I add or substract from the z-axis according to the mouse scroll.

But now I want to be able to rotate the 3d model with the mouse. Example: When i hold right mouse button and move the mouse up the model should rotate on it's x-axis(pitch) and if i move the mouse to the left/right it should rotate on y-axis(yaw). And I just couldn't do it.

The code bellow I get xpos/ypos of the cursor on the screen, calculate the offset and "trying to rotate the cube". The only problem is that i can't rotate the cuber normally if i move the mouse up the model rotate on the x-axis and y-axis with a little tilt and vice-versa.

This is the code in my rendering loop:

    shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), 
    (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.01f, 100.0f);
    shader.setMat4f("projection", projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view", view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::translate(modelm, object_translation);
    // Should rotate cube according to mouse movement
    //modelm = glm::rotate(modelm, glm::radians(angle), glm::vec3(0.0f));
    shader.setMat4f("model", modelm);

    renderer.draw(model, shader);

This is the call where i handle the mouse movement callback:

void mouseCallback(GLFWwindow* window, double xpos, double ypos)
{
if (is_rotating)
{
    if (is_first_mouse)
    {
        lastX = xpos;
        lastY = ypos;
        is_first_mouse = false;
    }

    // xpos and ypos are the cursor coords i get those with the 
    mouse_callback
    double xoffset = xpos - lastX;
    double yoffset = lastY - ypos;

    lastX = xpos;
    lastY = ypos;

    object_rotation.y += xoffset; // If i use yoffset the rotation flips
    object_rotation.x += yoffset;

    rotation_angle += (xoffset + yoffset) * 0.25f;
}
}

Mouse panning works fine too can't say the same for the rotation.

2
People can't help you without more information. Please describe what the error is you are experiencing, and what you are expecting. And also provide a Minimal, Reproducible Example. Your current code snippets don't tell us much.Human-Compiler
Wild guess: you're using radians when you think you're using degreesuser253751
@user253751 Degress gives even worst(super fast) rotation.Abdelbaki Boukerche
@AbdelbakiBoukerche Thank you for the edit, have an upvote! Before the edit there wasn't enough information to go on. I'm not familiar with GLM, but from the looks of it you're rotating after translating. Have you tried rotating first?Human-Compiler
@Human-Compiler Yea it didn't work, and the model start rotating around the world origin not it's local origin.Abdelbaki Boukerche

2 Answers

1
votes

I fixed it. After some research and asking i was told that u can only do one rotation at a time and i was trying to do both x/y-axis in the same time. Once i seperate the two rotations. object will now rotate on x-axis first then y-axis the problem was solved.

The code should be like this:

    shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.01f, 100.0f);
    shader.setMat4f("projection", projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view", view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::scale(modelm, glm::vec3(1.0f));
    modelm = glm::translate(modelm, glm::vec3(0.0f, 0.0f, -5.0f));
    // Handle x-axis rotation
    modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_x), glm::vec3(object_rotation_x, 0.0f, 0.0f));
    // Handle y-axis rotation
    modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_y), glm::vec3(0.0f, object_rotation_y, 0.0f));
    shader.setMat4f("model", modelm);

    renderer.draw(model, shader);
0
votes

You are storing your rotation as euler angle inside object_rotation.

I advised you to use:

glm::mat4 rotation = glm::eulerAngleYX(object_rotation.y, object_rotation.x); // pitch then yaw

or

glm::mat4 rotation = glm::eulerAngleXY(object_rotation.x, object_rotation.y); // yaw then roll

In your case both should do the job, I advised you in the future to store thoose informations inside your camera (eye, up, center) instead of your object, everything become more simpler.