Трехмерная линия выбора мыши

У меня есть 3D-сцена с тысячами строк. Я хочу иметь возможность выбирать ВСЕ 3D-линии в районе 10 пикселей курсора мыши (с перспективной проекцией). Я пытался использовать метод, основанный на уникальном цвете. Но мне этот способ не подходит, т.к. я не могу выбрать ВСЕ строки - только ближайшую. Есть ли приемлемое решение моей проблемы? OpenGL или DirectX - не важно.


person Alex    schedule 15.07.2012    source источник


Ответы (3)


Почему бы просто не вычислить расстояние между этими линиями и рассматриваемой точкой? Это двухмерное вычисление расстояния от линии до точки. Вероятно, вы могли бы реализовать это с помощью скрипта Perl, который вызывает исполняемый файл Python, который вызывает интерпретатор Lua, и все равно выполняет 100 000 из них в секунду.

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

person Nicol Bolas    schedule 15.07.2012
comment
Думаю, стоит упомянуть, что расстояние находится в проекции, на экране. Итак, сначала нужно найти экранные координаты концов линий и только потом вычислять расстояния. - person Alexey Frunze; 16.07.2012
comment
@AlexeyFrunze или вычислить мировые координаты линии, идущей в точку экрана, и выполнить сравнение линий в мировом пространстве. - person Martin Beckett; 16.07.2012
comment
@MartinBeckett Но тогда это явно перестанет быть 2D-решением. - person Alexey Frunze; 16.07.2012
comment
@AlexeyFrunze - да, но 3D расстояние не намного сложнее, чем 2D. Выполнение этого в координатах экрана может быть проблемой, если у вас есть перспектива. - person Martin Beckett; 16.07.2012
comment
@MartinBeckett: Как? Потому что у него есть разделение? - person Nicol Bolas; 16.07.2012
comment
@NicolBolas, если у вас хорошая перспектива, то один экранный пиксель может охватывать большой объем мира на больших расстояниях. Если вы попытаетесь сопоставить экранные координаты, у вас не будет большого разрешения. Если вы проецируете пиксель экрана обратно в мир, его точность не зависит от текущей проекции/перспективы. - person Martin Beckett; 16.07.2012
comment
@Мартин: О чем ты говоришь? Координата Z не имеет значения; все расстояния равны пространству окна X и Y (помните: ему нужны линии, находящиеся в пределах 10 пикселей от курсора. Следовательно, пространство окна). Что имеет большую точность, потому что это пространство окна: от 0 до размера окна. Что дает вам по крайней мере 3 десятичных цифры точности для работы. - person Nicol Bolas; 16.07.2012
comment
@NicolBolas - да, в этом случае, если вы ищете расстояние в пикселях, вам нужны экранные координаты - я просто указывал, почему не всегда выбор эквивалентной сети в мире / экране - person Martin Beckett; 17.07.2012

В старом OpenGL (‹= 2.1) вы можете использовать режим выбора, чтобы сделать именно это. Используйте gluPickMatrix(), чтобы выбрать небольшую область вокруг позиции курсора, инициализировать буфер выделения, перейти в режим выделения (glRenderMode(GL_SELECT)) и перерисовать сцену. Затем вернитесь из режима выбора, и ваш буфер выбора будет содержать полные имена (на самом деле идентификационные номера) всех нарисованных объектов, которые появляются в интересующей вас области. Вам придется немного изменить код отрисовки, чтобы добавлять имена (glPushName(objIndex)) вокруг каждого объекта, который вы визуализируете.

Это не самое эффективное использование современного графического оборудования, но оно всегда работает.

person Drew Hall    schedule 15.07.2012

Ни OpenGL, ни DirectX не сделают за вас эту работу, потому что они только рисуют. Что вы должны сделать, так это спроецировать все линии вашей сцены на экран и проверить, находится ли ближайшая точка к выбранной позиции ближе, чем желаемое максимальное расстояние. Вы можете ускорить это, сохранив линии в некоторой пространственной структуре подразделения (например, в дереве Kd или подобном), чтобы быстро отбросить все те строки, которые определенно не соответствуют вашим критериям.

person datenwolf    schedule 15.07.2012