1

I want to rotate and move a cat model in the direction that it's facing. However, when I rotate the cat, it's orbiting around the origin, which isn't what I want. DEMO

I know the formula for calculating the position of the model is:

// y is the up axis
x = distance * sin(theta);
z = distance * cos(theta);

This is the keyboard control function:

float translate_delta = 0.01f;
float rotate_delta = 0.1f;
int translate_press_num = 0;
int rotate_press_num = 0;

void special_callback(int key, int x, int y)
{
    if (key == GLUT_KEY_UP)
    {
        translate_press_num++;
    }
    else if (key == GLUT_KEY_DOWN)
    {
        translate_press_num--;
    }
    else if (key == GLUT_KEY_LEFT)
    {
        rotate_press_num--;
    }
    else if (key == GLUT_KEY_RIGHT)
    {
        rotate_press_num++;
    }
}

This is the model transformation:

mat4 model = mat4(1.0f);
float catAngle = rotate_delta * rotate_press_num * -45.0f;
float catX = translate_delta * translate_press_num * sin(catAngle * M_PI / 180);
float catZ = translate_delta * translate_press_num * cos(catAngle * M_PI / 180);

model = glm::translate(mat4(1.0f), vec3(catX, 0.0f, catZ)) *
        glm::rotate(mat4(1.0f), rotate_delta * rotate_press_num * glm::radians(-45.0f), vec3(0.0f, 1.0f, 0.0f));

I know that catAngle is affecting catX and catZ when rotating. I tried so many times, but I can't find a way to separate them.

genpfault
  • 51,148
  • 11
  • 85
  • 139
kirosc
  • 154
  • 1
  • 7
  • Keep the `catX` and `catZ` variables separate (or bundle them in a `glm::vec3`). Update the position **immediately** in your `special_callback` function, instead of waiting for the draw step. – Botje Oct 29 '19 at 08:26
  • see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) especially the links at the end ... – Spektre Oct 29 '19 at 21:01

1 Answers1

0

Define the cat position as a glm::vec3 catPosition in the same position where you keep other state variables.

In your key callback function:

void special_callback(int key, int x, int y) {
    float catAngle = rotate_delta * rotate_press_num * -45.0f;
    glm::vec3 displacement = translate_delta * glm::vec3(sin(catAngle * M_PI / 180), 0, cos(catAngle * M_PI / 180));

    if (key == GLUT_KEY_UP)
    {
        catPosition += displacement;
    }
    else if (key == GLUT_KEY_DOWN)
    {
        catPosition -= displacement;
    }
}

The model transformation then becomes:

mat4 model = 
    glm::translate(mat4(1.0f), catPosition) *
    glm::rotate(mat4(1.0f), rotate_delta * rotate_press_num * glm::radians(-45.0f), vec3(0.0f, 1.0f, 0.0f))
Botje
  • 26,269
  • 3
  • 31
  • 41