Способы реализации манипуляций с ручками в 3d виде - PullRequest
3 голосов
/ 06 мая 2009

Я создаю простое приложение для твердого моделирования. Пользователи должны иметь возможность манипулировать объектом как в ортогональном, так и в перспективе. Например, когда на экране есть поле, и пользователь нажимает на него, чтобы выбрать его, ему нужно получить «маркеры» по углам и в центре, чтобы пользователь мог навести курсор мыши на такую ​​ручку и перетащить его в увеличить или переместить коробку.

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

1) Рассматривать ручки как 3d-объекты. То есть для ящика добавьте маленькие ящики к сцене в углах «основного» ящика. Проблемы: это не будет работать в перспективе, мне нужно будет определить размер прямоугольников относительно текущего уровня масштабирования (маркеры должны иметь одинаковый размер, независимо от того, насколько увеличен / уменьшен пользователь)

2) Добавьте маркеры после рендеринга сцены. Выполните рендеринг в буфер за пределами экрана, определите 2-мерные положения углов и используйте обычные 2-мерные методы рисования для рисования маркеров. Проблемы: как я буду проводить тестирование? Мне нужно было бы также использовать двухэтапный подход к тестированию; Как нарисовать в 2D на 3D-изображение? Отступить к GDI?

Вероятно, есть больше проблем с обоими подходами. Существует ли отраслевой стандарт для решения этой проблемы?

Я использую OpenGL, если это имеет значение.

Ответы [ 4 ]

2 голосов
/ 06 мая 2009

Я бы рассматривал ручки как трехмерные объекты. Это дает много преимуществ - он более надежен, ведет себя хорошо, тестирование попаданий легко и т. Д.

Если вы хотите, чтобы маркеры имели постоянный размер, вы все равно можете рассматривать их как 3D-объекты, но вам придется масштабировать их размер в зависимости от расстояния до камеры. Это немного хлопотно, но так как обычно есть только несколько дескрипторов, и это, как правило, небольшие объекты, это должно быть хорошим решением для производительности.

Тем не менее, я бы сказал, что пусть шкалы масштабируются вместе со сценой. Пока вы выбираете стиль рендеринга для маркера, который выделяет их (т. Е. Ярко-оранжевые рамки и т. Д.), Эффекты перспективы (меньшие маркеры на заднем плане) фактически облегчают работу с ними для конечного пользователя во многих отношениях , Трудно получить ощущение глубины от 3D-сцены - эффекты перспективы на ручках помогают получить больше визуальных подсказок о том, насколько «глубоко» ручка находится на экране.

1 голос
/ 25 августа 2011

Я знаю, что вопрос действительно старый. Но на всякий случай кому-то это нужно:

Интерактивные методы в трехмерных сценах (часть 1): перемещение 3D-объектов с помощью мыши с использованием OpenGL 2.1

Статья хорошая и имеет интересный раздел ссылок внизу.

1 голос
/ 06 мая 2009

Я написал манипулятор с ручками для пакета 3D-редактирования и столкнулся с множеством таких же проблем.

Во-первых, есть манипулятор с открытым исходным кодом. Я не смог найти его в своем последнем поиске, возможно, потому, что есть множество названий этих вещей - 3d виджеты, вещицы, манипуляторы, карданные подвески и т. Д.

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

Идея Рида о сохранении их одинакового размера интересна для дескрипторов, которые существуют на объектах и ​​могут работать там. Для манипулятора я обнаружил, что это был скорее элемент трехмерного интерфейса, и его было бы гораздо удобнее использовать, если он не менял размер. У меня была ошибка, при которой размер определялся только на основе активного окна просмотра, что приводило к ужасным огромным / крошечным манипуляторам в других окнах просмотра, что было совершенно бесполезно. Если вы собираетесь добавить их на сцену, возможно, вы захотите добавить их для каждого окна просмотра или сделать так, чтобы они имели фиксированный размер.

1 голос
/ 06 мая 2009

Прежде всего, спроецируйте координаты рукоятки / угла на плоскость камеры (эффективно преобразуя их в 2D-координаты на экране; нормализуйте это по размерам экрана.)

Вот несколько простых кодов для включения ортогонального / 2D-наложения:

void enable2D()
{

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    int wind[4];
    glGetIntegerv(GL_VIEWPORT,wind);
    glOrtho(0,wind[2],0,wind[3],-1,1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
}


void disable2D()
{
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

enable2D () кэширует текущие матрицы вида / проекции и заменяет матрицу проекции на одну, нормализованную для экрана (то есть ширину / высоту экрана), и восстанавливает единичную матрицу для просмотра модели.

После этого вызова вы можете выполнять вызовы glVertex2f (), используя координаты экрана / пикселя, что позволяет рисовать в 2D! (Это также позволит вам выполнить хит-тест, поскольку вы можете легко получить текущие пиксельные координаты мыши.)

Когда вы закончите, вызовите disable2D, чтобы восстановить старые матрицы моделей / проекций:)

Самая сложная часть - это вычисления, где хитбоксы падают на 2D-плоскость, и работа с наложением (если два проецируются в одно и то же место, которое выбрать при нажатии?)

Надеюсь, это помогло:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...