Як реалізувати переклади, масштаб, обертання для обробки 3D-трансформацій об'єкта?


11

Я зараз в процесі розробки базового 3D-редактора. Він використовує OpenGL для візуалізації 3D-світу. Зараз моя сцена - це лише кілька коробок різного розміру, і я перебуваю на етапі, коли я хочу мати можливість вибирати кожне поле, а потім переміщувати / масштабувати / обертати його, щоб досягти будь-якої трансформації, яку я хочу.

Як я можу вирішити проблему впровадження як надання цих гізмотів інструмента (або ручок, так і того, як люди їх зазвичай називають), а також підбору їх на кожній осі, щоб виконати зміну перетворення за допомогою миші? Для наочності: введіть тут опис зображення

Наразі моє дослідження передбачає, що найчистішим підходом є встановлення вирівнюваної осі обмежувальної коробки на стрілку в gizmo та іншої на квадрат (ті, що переміщують об’єкт у площині, а не по одній осі), а потім кидає промінь від миші позицію і подивіться, з чим вона стикається. Але це все ще трохи занадто абстрактно для мене, я буду вдячний за подальші вказівки щодо того, як цей алгоритм піде (псевдокоду більш ніж достатньо)


1
Зазвичай ви передаваєтесь у світ із положенням миші і бачите, чи потрапила у вас штучка. Ви також можете перетворити gizmo в простір екрану, щоб там виявити зіткнення. Зазвичай ви хочете просто відстань від променя до типу сегмента лінії. Обертання зазвичай виконується у вигляді віртуальної кулі треку. Дивіться Мелакс у програмах Ігрові дорогоцінні камені 1. Переклад є майже точковим продуктом, а також масштабом.
RandyGaul

Відповіді:


9

У якийсь момент свого часу на e-on я дотримувався штук продуктової лінійки Vue .
Я можу вам сказати, це займе у вас кілька днів, повний робочий день.
Якщо ви не знайдете якусь бібліотеку чи супер розумний спосіб, класичним способом є отримання координати миші у вікні при натисканні, якщо її відносна координата до огляду, ви можете просто розділити x і y на ширину та висоту, ви отримати вектор (поплавок 2d) в діапазоні [0,1]. відніміть (0,5,0,5) до нього, щоб потрапити в діапазон [-0,5, 0,5] і для x, і y.
Потім ви робите промінь з цієї координати, використовуючи x і y просто як промінь x і y, і встановлюєте z на фокусну відстань. іноді співвідношення сторін - це біль у попі при цій операції. Деякі помилки та помилки проб допоможуть вам виправити.
Потім вам потрібно перевірити перетин з елементами gizmos, або у вас є сітка, яку ви створили, або змодельована в блендері чи іншому DCC, або сітчасті частини, які можуть чітко поєднуватися між собою ... Просто використовуйте цю частину сітки як промінь / запит перетину трикутника.
Або якщо у вас є, промінь / циліндр, промінь / сфера відповідно до вашого вигляду та деталей.
Потрібно мати підпрограми перетину, які здатні застосувати матрицю перетворення на примітивне їх зіткнення . Надзвичайно важливо, тому що ваша штучка перекладеться з об’єктом, котрий вона служить для переміщення, вона буде обертатися, і вона буде масштабуватись із обертом відстані до камери, щоб зберегти фіксований прогнозований розмір на екрані.
Тоді ви маєте частину взаємодії, найпростіше - це взяти дельту точки, коли миша вперше відбулася "миша вниз", і поточне положення "переміщення миші", в чистому 2D, і використовувати цю дельту як рух поточної осі у світовому просторі, помножене на деякі, kщо ви вирішуєте емпірично. Відповідно до ваших внутрішніх одиниць проти пікселя порівняно з поточною шкалою масштабування тощо.
Заключним кроком є ​​просто застосувати матрицю gizmo до маніпульованого об'єкта, щоб вона слідувала за нею.

Я кажу вам, що це досить дорога дорога в пекло, і якщо ви робите це у вільний час, вимагайте не один тиждень. Кілька тижнів, якщо ви повністю відкриєте поле. Більше одного місяця, якщо вихідні зайняті іншими видами діяльності :)

Я пропоную вам завантажити Embree 2.0 з Intel, щоб зробити для вас запит перетину променів / трикутників, тому вам не доведеться турбуватися про кодування цього. Або ви могли змилосердно скопіювати / вставити та адаптувати код з блендера ... Я думаю, вони перейшли на ліцензію Apache? Має бути можливим на законних підставах.


1
Дякую за вашу відповідь. Це справді корисно. Я знав, що не з’їхав з розуму, коли відчував, що переймається, мабуть, легким завданням. Я недооцінюю її складність і в кінцевому підсумку застряг у цій же проблемі днями. Наступного разу, коли я заходжу і вирішу це, я буду впевнений, що склав гарний план. Спасибі
Грімшо

0

Для маніпулятора-перекладача використовую наступний алгоритм:

1) Коли миша вниз, нам потрібно перевірити, чи перетинає стрілка промінь. Наприклад, ми вважаємо стрілку X. Ми створюємо Рея у світовому просторі (на основі камери та положення миші). Побудуємо площину, в якій лежить вісь x: її норма дорівнює V перетину X хрест V, де V - вектор від центру до камери, X - являє собою вісь x. Тоді ми перетинаємо промінь з площиною і тому знаходимо точку перетину у світових координатах. Потім проектуємо відрізок осі x і отриману точку назад на екран, знаходимо відстань між проектованим сегментом і проектованою точкою на екрані. якщо вона менше декількох пікселів, миша перетинає вісь. Також ми обчислюємо дельта-вектор світового простору між центром відбору та нашим перетином.

Цю процедуру ми робимо на 3 осі, тому знаходимо відстані до всієї осі. Знайдіть мінімальну відстань. тому ми виявили, з якою віссю миша перетинається.

2) Коли миша рухається. ми знаємо, по якій осі рухається об’єкт (від 1). ми знаходимо перетин світового простору променя з площиною (як у 1). додатково ми проектуємо точку перетину на лінію, по якій рухається об’єкт. остаточне положення маніпулятора = перехрестя + дельта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.