Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/17: Рейтинг темы: голосов - 17, средняя оценка - 4.59
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 876
Записей в блоге: 10
1

glm::rotate отрабатывает неожиданным образом

04.01.2021, 08:25. Показов 3258. Ответов 4

Author24 — интернет-сервис помощи студентам
Мне нужно сделать, чтобы в программе камера, смотрящая на кубик Рубика, могла передвигаться относительно него на 90 градусов по 4 направлениям по нажатию кнопок и слегка изменяла направление взгляда в зависимости от положения курсора мыши. Кнопки: WAXD или стрелки.

Проблема в том, что для пользователя после поворота куб исчезает (хотя если докрутить ещё 3 поворота, появляется опять), а в коде максимально то, что я смог локализовать, это строки 378-379:
C++
1
2
UnvariatedView = 
                    glm::rotate( fBaseForRotation(), M_PI_2, fvWorldRotationAxis );
эта функция отрабатывает для меня неожиданно. Я ожидаю, что (при нажатии кнопки A или влево) после rotate UnvariatedView получит 3 столбец (-5, 0, 0, 1) (или (5, 0, 0, 1)) , но он остаётся (0, 0, -5, 1).
Я сверялся с Tutorial 3 : Matrices, а именно с:
glm::rotate отрабатывает неожиданным образом
– вроде бы я понимаю суть операции правильно.

glm::rotate отрабатывает неожиданным образом


FollowingScene.7z
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.01.2021, 08:25
Ответы с готовыми решениями:

Cisco IP SLA и EEM не отрабатывает должным образом. В чем проблема?
Настроил на циске sla icmp-jitter, в котором посылается 100 пакетов раз в минуту. Конфигурация sla:...

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

Регулярка findstr отрабатывает на одном файле, но не отрабатывает на другом
Приветствую ! Сижу, ругаюсь матом в голос потому, что регулярка срабатывает на одном текстовом...

Результат запроса отрабатывает в консоли, но не отрабатывает в модуле
Доброго времени суток! Собственно проблема в следующем, есть запрос, который возвращает дату...

4
6107 / 3461 / 1406
Регистрация: 07.02.2019
Сообщений: 8,794
04.01.2021, 08:44 2
Цитата Сообщение от GoldenId Посмотреть сообщение
Проблема в том, что для пользователя после поворота куб исчезает
Это потому что смещение камеры не верное. Обоснуйте математически вот это:
C++
1
2
3
4
// Вычисляем 3x3 целочисленную матрицу ориентации камеры (неотклонённой)
im3BaseForRotation = glm::mat3( UnvariatedView );
// Вычисляем 3 вектор положения неотклонённой камеры
iv3BaseForRotation = glm::vec3( UnvariatedView * glm::vec4( 0, 0, 0, 1 ) ) / fCameraDistance;
А сами попробуйте исправить на это:
C++
1
2
3
4
5
// Вычисляем 3x3 целочисленную матрицу ориентации камеры (неотклонённой)
mat4 invView = glm::inverse(UnvariatedView);
im3BaseForRotation = glm::transpose(mat3(invView));
// Вычисляем 3 вектор положения неотклонённой камеры
iv3BaseForRotation =  invView[3] / (-fCameraDistance * invView[3][3]);
1
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 876
Записей в блоге: 10
04.01.2021, 10:59  [ТС] 3
Цитата Сообщение от zayats80888 Посмотреть сообщение
Это потому что смещение камеры не верное. Обоснуйте математически вот это:
До поворота смещение камеры (0, 0, -5). После поворота должно быть (-5, 0, 0)

C++
1
2
// Вычисляем 3x3 целочисленную матрицу ориентации камеры (неотклонённой)
im3BaseForRotation = glm::mat3( UnvariatedView );
Здесь я просто привожу floating-point матрицу поворота к целочисленной (потому что я хочу хранить целочисленную ориентацию, ориентация вне поворота (базы для поворота) мне нужна только вдоль осей).

C++
1
2
// Вычисляем 3 вектор положения неотклонённой камеры
iv3BaseForRotation = glm::vec3( UnvariatedView * glm::vec4( 0, 0, 0, 1 ) ) / fCameraDistance;
Здесь я делаю то же для направления на положение камеры (относительно world-начала координат). В iv3BaseForRotation я хочу хранить единичный целочисленный вектор направения на камеру, а её расстояние от начала координат храню в fCameraDistance. Потому, что если хранить, например в glm::tvec3<int>, то с одной стороны нельзя будет указать расстояние от начала координат, например 3.5, а с другой стороны, кто меня страхует, что я не получу в нём что-нибудь вроде (3, 1, 0), что принципиально противоречит моему подходу? Что-то вроде строгого хранения данных.

Поправьте меня, если я неправ, вот это:
C++
1
invView[3][3]
всегда должно давать просто 1.0f для корректно инициализированной матрицы преобразования.

C++
1
2
3
4
5
// Вычисляем 3x3 целочисленную матрицу ориентации камеры (неотклонённой)
mat4 invView = glm::inverse(UnvariatedView);
im3BaseForRotation = glm::transpose(mat3(invView));
// Вычисляем 3 вектор положения неотклонённой камеры
iv3BaseForRotation =  invView[3] / (-fCameraDistance * invView[3][3]);
Хорошо, это работает, но почему, мне непонятно. Причём здесь взятие обратной матрицы и транспонирование, если и UnvariatedView и im3BaseForRotation у меня определяют преобразование в одном и том же направлении (нет времени думать, 5 минут редактирования)?

Добавлено через 5 минут
Для того, чтобы разобраться, почему поворот на
C++
1
#define M_PI_2 (3.141592f * 0.5f)
даёт поворот на 180° создавать отдельную тему?
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
04.01.2021, 11:30 4
Цитата Сообщение от GoldenId Посмотреть сообщение
#define M_PI_2 (3.141592f * 0.5f)
а почему M_PI_2 надо умножать(pi * 0,5), а не делить ли надо pi/2 или я чего то не знаю?
https://docs.microsoft.com/en-... w=msvc-160
0
6107 / 3461 / 1406
Регистрация: 07.02.2019
Сообщений: 8,794
04.01.2021, 20:03 5
Лучший ответ Сообщение было отмечено GoldenId как решение

Решение

GoldenId, это не математическое обоснование .
Цитата Сообщение от GoldenId Посмотреть сообщение
Причём здесь взятие обратной матрицы и транспонирование
Если просто в двух словах, ваша матрица вида(fBaseForRotation()) - это комбинация двух преобразований - поворот и перенос (R * T). Это простая матрица. Что бы после узнать преобразование СК(системы координат) вида в мировой СК, нужно найти обратную матрицу. Четвёртый столбец этой матрицы и будет описывать положение камеры в мировой СК. Оно вам и нужно, что бы вычислить необходимое смещение(со знаком минус, т.к. <перенос камеры> = -<перенос мира>). Транспонирование верхней левой 3х3 матрицы invView - просто так, раз уж инвертировали уже(в вашем случае это "чистая" матрица вращения, значит R-1 = RT, можно было просто im3BaseForRotation = mat3(UnvariatedView);.
Цитата Сообщение от GoldenId Посмотреть сообщение
всегда должно давать просто 1.0f для корректно инициализированной матрицы преобразования.
Опять же, в вашем случае преобразование не затрагивает гомогенную компоненту, поэтому да, она будет единицей. Я просто по привычке перевожу в аффиные координнаты.

Ну и в целом, в вашем простом случае всё это избыточно. Можно эту ветку кода упростить так:
C++
1
2
3
4
5
6
7
8
9
10
11
// Если дошли до конечной фазы вращения
if (currentRotationAngle >= M_PI_2)
{
    rotation = false;
    // вместо вычисления базовой из обратной, просто поворачиваем базовую
    im3BaseForRotation = mat3(glm::rotate(glm::mat4(im3BaseForRotation), M_PI_2, fvWorldRotationAxis));
    // в пространстве камеры смещение у вас всегда вдоль оси z, поэтому проецируем его на мировые оси
    iv3BaseForRotation = glm::transpose(glm::mat3(im3BaseForRotation)) * vec3(0.0f, 0.0f, -1.0f);
    // и теперь считаем матрицу вида
    UnvariatedView = fBaseForRotation();
}
Цитата Сообщение от GoldenId Посмотреть сообщение
чтобы разобраться, почему поворот на
#define M_PI_2 (3.141592f * 0.5f)
даёт поворот на 180° создавать отдельную тему?
У вас немного кривая обработка ввода. Из-за glfwSetInputMode( window, GLFW_STICKY_KEYS, GL_TRUE ); и того, что glfwGetKey вызывается только по условию if ( !rotation ), у вас поворот выполняется дважды. Что бы этого не было, либо выключите GLFW_STICKY_KEYS, либо снимайте флаги состояния glfwGetKey вне условия(а в условии только обрабатывайте их), либо сделайте по человечески обработку событий внутри колбэка.
1
04.01.2021, 20:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.01.2021, 20:03
Помогаю со студенческими работами здесь

Камера glm
Здравствуйте, вот я смотрел много примеров камеры, и нигде не нашед такого, где использовался бы...

Переменные glm::ortho
Простой вопрос: какие первые 4 значения принимает функция glm::ortho () ? В описании написано...

Задачка с unproject (glm)
В общем я что-то туплю. (опять) Целый день просидел с тем что бы найти координаты усеченной...

Glm::ortho не работает
Программка из Vulkan Tutorial, рисует простой треугольник, с вершинами: { { 0.0f, -0.1f } },...

Хранить ли векторы в glm::vec4?
Если я загружаю 3д модельку, или ещё что-то, то правильно ли хранить все векторы в массиве из...

GLM , функции трансформации матриц
Здравствуйте,в общем столкнулся с проблемой библиотеки glm связана с ее функциями для трансформации...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru