Я пытался выяснить это в течение нескольких часов, и я просто не могу найти решение для этого: То, что я пытаюсь достичь, - это преобразование вектора ориентации в 3 glm::rotation
звонки.Yaw, Pitch и roll to glm :: rotate
У меня есть цилиндр, расположенный в (0, 0, 0)
с определенным радиусом и высотой. С Leap Motion SDK Я выполнения отслеживания инструмент, который дает мне положение наконечника и направление вектора (что выражается как единичный вектор в том же направлении, что и наконечник):
Источник: https://developer.leapmotion.com/documentation/skeletal/java/api/Leap.Pointable.html
Кроме того, yaw
, pitch
и roll
могут быть извлечены формы этого вектора, используя следующие функции SDK:
/// The yaw angle in radians.
///
/// Yaw is the angle between the negative z-axis and the projection of
/// the vector onto the x-z plane. In other words, yaw represents rotation
/// around the y-axis. If the vector points to the right of the negative z-axis,
/// then the returned angle is between 0 and pi radians (180 degrees);
/// if it points to the left, the angle is between 0 and -pi radians.
///
/// \image html images/Math_Yaw_Angle.png
///
/// @returns The angle of this vector to the right or left of the negative z-axis.
float yaw() const
{
return std::atan2(x, -z);
}
/// The pitch angle in radians.
///
/// Pitch is the angle between the negative z-axis and the projection of
/// the vector onto the y-z plane. In other words, pitch represents rotation
/// around the x-axis.
/// If the vector points upward, the returned angle is between 0 and pi radians
/// (180 degrees); if it points downward, the angle is between 0 and -pi radians.
///
/// \image html images/Math_Pitch_Angle.png
///
/// @returns The angle of this vector above or below the horizon (x-z plane).
float pitch() const {
return std::atan2(y, -z);
}
/// The roll angle in radians.
///
/// Roll is the angle between the negative y-axis and the projection of
/// the vector onto the x-y plane. In other words, roll represents rotation
/// around the z-axis. If the vector points to the left of the negative y-axis,
/// then the returned angle is between 0 and pi radians (180 degrees);
/// if it points to the right, the angle is between 0 and -pi radians.
///
/// \image html images/Math_Roll_Angle.png
///
/// Use this function to get roll angle of the plane to which this vector is a
/// normal. For example, if this vector represents the normal to the palm,
/// then this function returns the tilt or roll of the palm plane compared
/// to the horizontal (x-z) plane.
///
/// @returns The angle of this vector to the right or left of the y-axis.
float roll() const {
return std::atan2(x, -y);
}
В моем OpenGL цикла рендеринга, я извлекая положение наконечника, а также в направлении против каждого кадра. Я передаю матрицу модели в качестве единой переменной моих шейдеров следующим образом:
cylinder->ResetModelMatrix(); // Set model matrix to identity
glm::vec3 translation = glm::vec3(toolTipPosition.x, toolTipPosition.y, toolTipPosition.z);
cylinder->TranslateModel(translation);
cylinderProgram->SetUniform("modelMatrix", cylinder->GetModelMatrix());
Только с переводом, это хорошо работает и выглядит примерно так (с цилиндр всегда направлен вверх):
Проблема возникает, когда я пытаюсь повернуть цилиндр в соответствии с ориентацией инструмента Leap. У меня есть следующий код:
yaw = toolDirection.yaw() * Leap::RAD_TO_DEG;
// similarly for pitch and roll
cylinder->Rotate(yaw, glm::vec3(0.0f, 1.0f, 0.0f));
// pitch around (1, 0, 0) and roll around (0, 0, 1)
Однако, я не получаю правильные ориентиры и цилиндр «мерцающий» и прыгает между множеством ориентаций, когда я пытаюсь применить это.
важные функции преобразования находятся в интерфейсе, из которого наследует мой класс цилиндр ...
void Drawable::ResetModelMatrix()
{
this->modelMatrix = glm::mat4(1.0f);
}
void Drawable::TranslateModel(glm::vec3 translationVector)
{
this->modelMatrix = glm::translate(this->modelMatrix, translationVector);
}
void Drawable::RotateModel(float angle_in_degrees, glm::vec3 axisOfRotation)
{
this->modelMatrix = glm::rotate(this->modelMatrix, angle_in_degrees, axisOfRotation);
}
void Drawable::ScaleModel(glm::vec3 scalingVector)
{
this->modelMatrix = glm::scale(this->modelMatrix, scalingVector);
}
... с modelMatrix
неоспоримым переменной-члена.
Я просмотрел много похожих вопросов по теме вращения в OpenGL и вообще, но я не совсем уверен, что именно проблема с моим кодом здесь.
Для поворота вы должны сначала перевести свой цилиндр в начало координат и выполнить свое вращение и перевести назад. [Функция вращения работает корректно, когда ваша опорная точка является источником.] –
Фактически, то же самое происходит, когда цилиндр центрирован в начале координат без какого-либо перевода. – Schnigges
Я предполагаю, что красная линия на изображении - ваш цилиндр. Если вы хотите повернуть его вокруг зеленого шара, сначала вы должны применить перевод на свой цилиндр так, чтобы ваш зеленый шар был на месте. Чем вы можете применить поворот к вашему цилиндру, и, наконец, вы сможете перевести назад свой цилиндр. [Здесь вам нужно, чтобы нижний край цилиндра находился в начале координат, а не в центре цилиндра) –