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.
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))