Как правильно реализовать интерактивные операции ротации - PullRequest
0 голосов
/ 19 июня 2020

В последнее время я хочу добиться интерактивных операций вращения, как это можно сделать в meshlab : enter image description here

По сути, достигается вращение с тремя степенями свободы. . Я визуализирую эти операции как следующие коды с помощью GLFW :

static void mouse_move_callback(GLFWwindow* window, double xpos, double ypos){
...
do{
        //perform rotation operations only if keeping the right mouse key pressed
        if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_RELEASE) {
            g_clr_right_mouse = true;
            break;
        }
        /*clear mouse state once transferred from release state 
          to pressed state to prevent from a instant flicker*/
        if(g_clr_right_mouse){
            g_lastX = xpos;
            g_lastY = ypos;
            g_clr_right_mouse = false;
        }

        float xoffset = xpos - g_lastX; //let movement from down to top positive
        float yoffset = g_lastY - ypos;
        g_lastX = xpos;
        g_lastY = ypos;

        //do counterclockwise rotation around x-asis with movement in y direction
        glm::mat4 r1 = glm::rotate(glm::mat4(), glm::radians(-yoffset * 0.5f), glm::vec3(1.0f,0.0f,0.0f));
        //do counterclockwise rotation around y-asis with movement in x direction
        glm::mat4 r2 = glm::rotate(glm::mat4(), glm::radians( xoffset * 0.5f), glm::vec3(0.0f,1.0f,0.0f));
        glm::mat4 tmp = r2 * r1 * g_model;
        for(int i=0; i<3; i++)
            g_model[i] = tmp[i];
        return ;
    }while(false);
}

Эти коды расположены здесь , и можно найти весь проект здесь , который можно скачать и собрать. Наконец, он работает следующим образом: enter image description here Однако моя реализация может выполнять операции вращения только с 2 степенями свободы, я добавляю обратный вызов клавиатуры для достижения вращения вокруг оси z:

void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mod){
    if(glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS){
        glm::mat4 r3 = glm::rotate(glm::mat4(), glm::radians(3.0f), glm::vec3(0,0,1.0f));
        glm::mat4 tmp = r3 * g_model;
        for(int i=0; i<3; i++)
            g_model[i] = tmp[i];
    }else if(glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS){
        glm::mat4 r3 = glm::rotate(glm::mat4(), glm::radians(-3.0f), glm::vec3(0,0,1.0f));
        glm::mat4 tmp = r3 * g_model;
        for(int i=0; i<3; i++)
            g_model[i] = tmp[i];
    }
}

Итак, мой вопрос: как прилично достичь интерактивных операций вращения 3 степеней свободы только с помощью движения мыши?

1 Ответ

0 голосов
/ 19 июня 2020

Вам нужно нарисовать мяч, чтобы сделать его интуитивно понятным.

При опускании мыши вы помещаете якорь на мяч прямо под указателем мыши. Если щелчок за пределами шара, вы используете ближайшую точку на шаре.

По мере движения мыши вы вращаете шар так, чтобы точка привязки следовала по кратчайшему пути, чтобы он оставался прямо под мышью указатель. Если указатель мыши находится вне шара, то используется ближайшая точка на шаре.

Может быть, , это поможет.

...