OpenGL перевод и вращение объекта

0

У меня есть объект, который перемещается по кругу. Объект - рыба.
Перемещение:

mesh->objectModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(5.0f * sin(elapsedTime), initialY, 5.0f * cos(elapsedTime)));

Мне нужно рассчитать оборот, чтобы переместить рыбу вперед (сначала голову). Что-то вроде этого:

    mesh->objectModelMatrix = glm::rotate(mesh->objectModelMatrix, elapsedTime, glm::vec3(0.0f, 0.0f, 1.0f));

Непреобразованная ориентация рыбы имеет голову, направленную вправо.

Я не могу найти правильную формулу.

  • 0
    Какова оригинальная ориентация рыбы? Голова указывает вправо (то есть в положительном направлении по оси X)?
  • 0
    Да, голова указывает направо.
Теги:
opengl

1 ответ

0
Лучший ответ

Как вы, наверное, знаете, основным параметрическим уравнением для круга является: rad радиус и phi угол в диапазоне [0, 2 * PI]:

x = rad * cos(phi)
y = rad * sin(phi)

Поскольку phi развертки от 0 до 2 * PI, это начинается справа (положительная ось x) и движется против часовой стрелки. Это означает, что начальное движение вверх, в направлении положительной оси y.

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

Для ориентации против часовой стрелки мы можем обобщить начальную точку, просто добавив начальный угол. Мы также будем выражать угол как функцию времени t:

x = rad * cos(phiStart + speed * t)
y = rad * sin(phiStart + speed * t)

Это дает вам компоненты перевода. Для вращения рыбы, так как ее базовое положение указывает направо, но начальное движение кругового движения направлен вверх, нам нужно вращать его на 90 градусов, прежде чем применять круговое движение. Это означает, что 0.5 * PI (90 градусов) добавляются к углу, используемому для перевода:

rotAng = 0.5 * PI + phiStart + speed * t

Не знакомясь с используемой матричной библиотекой, я надеюсь, что он использует стандартный порядок для умножения матриц. Таким образом, выраженный в коде, приведенное выше выглядит примерно так:

float phiStart = 0.0f;  // start at right, set different start angle if desired
float phi = phiStart + elapsedTime;  
mesh->objectModelMatrix =
    glm::translate(glm::mat4(1.0f),
                   glm::vec3(5.0f * cos(phi), initialY, 5.0f * sin(phi)));
mesh->objectModelMatrix =
    glm::rotate(mesh->objectModelMatrix,
                0.5f * M_PI + phi, glm::vec3(0.0f, 0.0f, 1.0f));

Для перемещения по часовой стрелке вместо этого мы можем просто инвертировать знак угла. Единственное другое отличие состоит в том, что, поскольку начальное движение теперь вниз, начальное вращение рыбы также на 90 градусов по часовой стрелке, что соответствует -0.5 * PI:

float phiStart = 0.5f * M_PI;  // start at top, set different start angle if desired
float phi = phiStart - elapsedTime;  
mesh->objectModelMatrix =
    glm::translate(glm::mat4(1.0f),
                   glm::vec3(5.0f * cos(phi), initialY, 5.0f * sin(phi)));
mesh->objectModelMatrix =
    glm::rotate(mesh->objectModelMatrix,
                -0.5f * M_PI + phi, glm::vec3(0.0f, 0.0f, 1.0f));

Я не мог найти четкую документацию для используемой библиотеки матриц. Возможно, что второй аргумент glm::rotate() - это угол в градусах вместо радианов. Если это так, те призывы к двум случаям становятся:

    glm::rotate(mesh->objectModelMatrix,
                90.0f + phi * (180.0f / M_PI), glm::vec3(0.0f, 0.0f, 1.0f));

    glm::rotate(mesh->objectModelMatrix,
                -90.0f + phi * (180.0f / M_PI), glm::vec3(0.0f, 0.0f, 1.0f));
  • 0
    Благодарю за ваш ответ. Я запрограммировал это, но перевод намного быстрее, чем вращение. Мне нужно как-то ускорить скорость вращения. ElapsedTime увеличивается на 1 каждую секунду.
  • 0
    Может быть, glm::rotate() принимает угол в градусах? Умножьте аргумент угла в этих вызовах на (180.0f / M_PI) и посмотрите, работает ли он.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню