Как вращать объекты в OpenGL относительно локальной или глобальной оси

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

Как повернуть изображение поверх глобальные оси, а не локальные?

вращение объектов в opengl

Как вращать вершины точно так же, как с glRotatef () в OpenGL ?

Повернуть объект вокруг трех осей в OpenGL

Повернуть объект по его собственным осям в OpenGL

Можно ли повернуть объект вокруг собственной оси, а не вокруг оси базовой координаты?

Вращение OpenGL - локальные и глобальные оси

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

У меня есть 3D-модель объекта в формате STL, я сделал парсер STL и отлично могу визуализировать объект.

Когда я пытаюсь повернуть его, я получаю разные странные результаты.

Я использую SharpGL (компонент Scene).

Я попытался написать «эффект», который (пока) управляется тремя отдельными полосами прокрутки, но это будут данные с датчиков.

Я хотел сделать это как эффект, потому что (теоретически) у меня могло быть больше объектов в сцене, и мне нужно было повернуть только конкретный (а также в образовательных целях, поскольку я относительно новичок в OpenGL).

Я попытался повернуть объект, используя кватернионы, умножив их и сгенерировав матрицу вращения, а затем применив gl.MultMatrix(transformMatrix.AsColumnMajorArray).

Я также пробовал gl.Rotate(angleX, 1, 0, 0) (и аналогичный для осей Y и Z).

В зависимости от порядка умножения кватернионов или операторов gl.Rotate(...), я мог бы заставить объект вращаться вокруг локальной оси (первая), что-то странное (вторая) и третья «мировая». Например, если бы я сделал это с кватернионами qX*qY*qZ и получил бы из них матрицу вращения, я бы получил (я думаю) вращения вокруг локальной оси X, «произвольной» оси Y и мировой оси Z.

Часть, которую я не могу понять, заключается в том, что когда я применяю gl.Rotate(dx, 1, 0, 0) (и другие для поворота Y и Z) внутри события Scroll трекбара, вся сцена вращается вокруг осей X, Y и Z и в этом порядке, и именно так, как я ожидал, вращение должно произойти.

Моя единственная проблема с этим подходом заключается в том, что вся сцена вращается. Так что, если бы я (гипотетически) захотел нарисовать комнату вокруг объекта, вся комната тоже повернулась бы, чего я не хочу.

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

В конце концов, я хочу, чтобы мой объект (Polygon в терминах SharpGL) вращался вокруг своих собственных осей (или вокруг «мировых» осей, но был последовательным).

РЕДАКТИРОВАТЬ:

Я поместил проект в свой Dropbox: https://goo.gl/1LzNhn

Если кто-то захочет взглянуть на это, мы будем благодарны за любую помощь.

В MainForm функция TbRotXYZScroll имеет код трекбара, а проблема заключается в классе Rotation (по крайней мере, я так думаю).

Поверните X, Y и Z, скажем, на 45 градусов в указанном порядке. Вроде все отлично работает. Теперь поверните X, Y и Z еще на 30 или около того градусов, попытайтесь визуализировать, вокруг какой оси происходит вращение при вращении ...
X кажется всегда миром, а Z кажется всегда локальным, в то время как Y - что-то среднее (изменение порядка вращения меняет это).

Переход к функции TbRotXYZScroll и изменение метода на 2 делает то, что я хочу (кроме поворота всей сцены). Пробовал кватернионы, и они дают точно такой же результат, поэтому Я, должно быть, делаю что-то не так ...
Изменение его на 1 дает аналогичный результат, но это применимо вращение только к полигонам (не то, что визуализируется, поскольку оно включает также и локальные оси координат).


person nurchi    schedule 06.05.2015    source источник


Ответы (1)


В конце концов, я хочу, чтобы мой объект (Многоугольник в терминах SharpGL) вращался вокруг своих собственных осей (или вокруг "мировых" осей, но был последовательным).

Я думаю, этот ответ, который вы задали, каким-то образом объясняет ситуацию. Чтобы произвести вращение вокруг оси объекта:

1. Выполните перемещение / вращение вашего объекта и сделайте так, чтобы ось объекта перекрывала одну из основных осей (x, y или z).

2. Произведите ротацию

3. Верните объект в исходное положение. (просто верните перевод / повороты на шаге 1)

Примечание. При этом следует учитывать одну вещь: openGL применяет преобразования в обратном порядке.

Пример:

glRotatef(90,1,0,0); 
glTranslatef(-5,-10,5); 
drawMyObject();

В этом случае opengl сначала переведет ваш объект, а затем повернет. Поэтому при написании ваших преобразований учитывайте это. Вот мой ответ, который может дать вам представление .

person Berke Cagkan Toptas    schedule 06.05.2015
comment
Проблема не в переводе, так как мой объект находится в мировом происхождении (если только я чего-то не понимаю). Хотя это начало не в центре объекта, объект находится в первом октанте (где X, Y и Z все> 0). Смещение его таким образом, чтобы геометрический центр объекта совпадал с исходной точкой, изменяет точку вращения, но не влияет на исходную проблему. - person nurchi; 07.05.2015
comment
Спасибо, Чагкан, внимательное прочтение вашего пункта №1 привело меня в правильном направлении. - person nurchi; 08.05.2015