Модераторы: Rickert

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как выбрать объект в 3d сцене, выбор объекта в opengl 3d 
:(
    Опции темы
Ravend
Дата 22.7.2005, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 19.7.2005

Репутация: нет
Всего: 1



Привет, All!

При помощи opengl формирую некоторую 3d сцену с набором объектов, с возможностью маштабирования и вращения.
Теперь требуется по щелчку мышью работать с выбранным объектом (в случае если под курсор попало несколько объектов предлагать выбор из списка).

Кто нибудь подскажет где можно почитать как в opengl произвести выбор объекта при помощи мыши?


Спасибо.
PM MAIL   Вверх
mr.DUDA
Дата 22.7.2005, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 7
Всего: 232



Честно говоря, не знаю как в OpenGL... Во многих движках есть функции типа RayQuery, возвращающие меш или даже треугольник по координатам в отрендеренной картинке для заданного viewport-а.


--------------------
user posted image
PM MAIL WWW   Вверх
chipset
Дата 23.7.2005, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 2
Всего: 164



На гейм-дев есть статья Выбор обьектов средствами OpenGL smile


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
gepard
Дата 24.7.2005, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 8
Всего: 40



chipset
Пора отвыкать от этого говноДева.Ру! Там то, как выбирать объекты, если ты их строишь на основе списков OpenGL'а...
Аналитическая геометрий - вот веь, которую должен знать человек + мат. ан. Тогда он может что-то "булькнуть" в разработке игр.
Чтобы выбрать объект, делаем так:
1)Определяем Bounding Box для всех объектов.
2)Все объекты имеют свой id номер, который не повторяется у двух любых объектов.
3)По пунктам в исходник:
Код

void AWorld::objSelection(CPoint point)//Передаются координаты мыши.
{
    //Определяем пару переменных
    double projection[16], modelview[16], wx, wy, wz, vz;
    unsigned int counter = 0, min, n, i,  j, objs_array[256];
    float a, b, c, d, p, ml;
    int viewport[4];
    bool yes = 0;
    //Выдёргиваем значения матриц
    glGetIntegerv(GL_VIEWPORT, viewport);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
         //Читаем глубину пикселя под курсором
    glReadPixels(point.x, point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vz);
         //Вычисляем точку курсора в пространстве
    gluUnProject(point.x, point.y - 1, vz, modelview, projection, viewport, &wx, &wy, &wz);//(wx, wy, wz) - координаты курсора в пространстве OpenGL.
    p1.x = (float)wx;//Присваеваем их переменной - структуре, в которой описано только три элемента: float x, y, z; Это глобальная переменная.
    p1.y = (float)wy;
    p1.z = (float)wz;

    p2.x = perspCamera.view.x;//Вторая такая же переменная, которая принемает значения точки, куда смотрит камера. Этот случай работает только в том случае, если курсор находится по середине игрового экрана. В ином случае надо будет вызывать две функции gluUnProject
    p2.y = perspCamera.view.y;
    p2.z = perspCamera.view.z;

    for (j = 0; j < objCount; j++)//Цикл по всем объектам
        for (i = 0; i < 6; i++)//Цикл по всем шести граням Bounding Box'а
        {
                           //Ниже идёт вычисление точки пересечения линии, построенной по двум точкам p1 и p2 и грани Bounding Box'а.
                           //Это всё из аналитической геометрии. Поясню, что objects - указатель на объекты. bbox - указатель на грань Bounding Box'а - структура, элементами которой являются
                           //вершины - vertex - 4 штуки у каждой грани. Каждая вершина - стуртура того же тпи, что и p1(или p2).
            a = ((objects[j].bbox[i].vertex[1].y - objects[j].bbox[i].vertex[0].y)*(objects[j].bbox[i].vertex[2].z - objects[j].bbox[i].vertex[0].z)-
                ( objects[j].bbox[i].vertex[2].y - objects[j].bbox[i].vertex[0].y)*(objects[j].bbox[i].vertex[1].z - objects[j].bbox[i].vertex[0].z));

            b = ((objects[j].bbox[i].vertex[1].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[2].z - objects[j].bbox[i].vertex[0].z)-( objects[j].bbox[i].vertex[2].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[1].z - objects[j].bbox[i].vertex[0].z));

            c = ((objects[j].bbox[i].vertex[1].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[2].y - objects[j].bbox[i].vertex[0].y)-( objects[j].bbox[i].vertex[2].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[1].y - objects[j].bbox[i].vertex[0].y));

            d = (-objects[j].bbox[i].vertex[0].x)*((objects[j].bbox[i].vertex[1].y - objects[j].bbox[i].vertex[0].y)*(objects[j].bbox[i].vertex[2].z - objects[j].bbox[i].vertex[0].z)-( objects[j].bbox[i].vertex[2].y - objects[j].bbox[i].vertex[0].y)*(objects[j].bbox[i].vertex[1].z - objects[j].bbox[i].vertex[0].z))+( objects[j].bbox[i].vertex[0].y)*((objects[j].bbox[i].vertex[1].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[2].z - objects[j].bbox[i].vertex[0].z)-( objects[j].bbox[i].vertex[2].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[1].z - objects[j].bbox[i].vertex[0].z))+(-objects[j]
.bbox[i].vertex[0].z)*    ((objects[j].bbox[i].vertex[1].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[2].y - objects[j].bbox[i].vertex[0].y)-( objects[j].bbox[i].vertex[2].x - objects[j].bbox[i].vertex[0].x)*(objects[j].bbox[i].vertex[1].y - objects[j].bbox[i].vertex[0].y));

            p = (-a*p1.x-b*p1.y - c*p1.z - d)/(a*(p2.x - p1.x) + b*(p2.y - p1.y) + c*(p2.z - p1.z));
 
            crosser.x = (p2.x - p1.x)*p + p1.x;//Итоговая точка пересечения плоскости грани Bounding Box'а и линии, которая построена по двум точкам - crosser
            crosser.y = (p2.y - p1.y)*p + p1.y;
            crosser.z = (p2.z - p1.z)*p + p1.z;

            if(здесь должно написать условие принадлежности точки к многоугольнику(в нашем случае - четырёхугольнику))
            {
                objs_array[counter++] = j;//номер выбранного объекта записываем.
                break;
            }
        }...
}

Там есть ещё код, но это уже дороботки.
Хочу сказать, что самый простой и неэффективный способ выбора объекта, к тому же ещё и самый трудоёмкий для компьюетра, в плане вычислений.

Это сообщение отредактировал(а) gepard - 24.7.2005, 16:10


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 24.7.2005, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 7
Всего: 232



gepard, этот код будет проверять попадание только в прямоугольные области экрана. То есть, если у меня есть mesh, имеющий сложную форму (к примеру - бублик), то данный код вернёт прямоугольный ящик, полностью окружающий мой бублик, но несколько бубликов, вложенных друг в друга под разными углами и смещениями, данный код не обработает.

Другое дело - если есть алгоритм, обрабатывающий полигоны. То есть, нужно пробежаться по bounding box-ам всех mesh-ей, попадающих в проверяемую точку, и далее проверить все полигоны каждого меша, спроецированные в viewport, т.е. "просматриваемые" камерой, в координатах которой мы работаем. Вот тогда есть реальная возможность определить меш (модель) и даже полигон, в который попадает курсор мыши. Пример приводить не стану, т.к всё слишком сильно зависит от используемой модели (D3D, OGL) и движка. К примеру, лично я использую порт Ogre под .NET - там свой собственный алгоритм определения, попала ли точка в заданный меш, и в какой именно полигон меша она попала.


--------------------
user posted image
PM MAIL WWW   Вверх
gepard
Дата 25.7.2005, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 8
Всего: 40



Цитата(mr @ 24.7.2005, 19:21)
gepard, этот код будет проверять попадание только в прямоугольные области экрана. То есть, если у меня есть mesh, имеющий сложную форму (к примеру - бублик), то данный код вернёт прямоугольный ящик, полностью окружающий мой бублик, но несколько бубликов, вложенных друг в друга под разными углами и смещениями, данный код не обработает.

Не, друг, ты не прав. Добавь ниже кодом отбор по отдалённости объекта от камеры и будет тебе выбор объектов, наложенных друг на друга. При повороте объекта - персчитывается его Bounding Box, а следовательно угол наклона не будет иметь значения, по своей сути.
Цитата(mr @ 24.7.2005, 19:21)
Другое дело - если есть алгоритм, обрабатывающий полигоны.

Всё до безумия просто: нам просто надо, вместо вершин грани Bounding Box'а указать вершины нужного нам полигона(все по очереди) и получим точку пересечения плоскости полигона и(если он выпуклый) и "линии выбора".


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
DENNN
Дата 25.7.2005, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 3
Всего: 43



Цитата(mr @ 24.7.2005, 19:21)
то данный код вернёт прямоугольный ящик, полностью окружающий мой бублик, но несколько бубликов, вложенных друг в друга под разными углами и смещениями, данный код не обработает.

Это способ хорошо использовать в качестве первого приближения. С отобранными объектами уже можно произвести аналитические операции.

P.S. найти пересекает ли прямая многоугольник, заданный вершинами не так уж и сложно.
PM ICQ   Вверх
Ravend
Дата 25.7.2005, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 19.7.2005

Репутация: нет
Всего: 1



Народ спасибо за ответы, общая идея ясна, но есть ещё вопрос.

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

Вопрос как работать с визуальными координатами объекта?

Это сообщение отредактировал(а) Ravend - 25.7.2005, 11:04
PM MAIL   Вверх
DENNN
Дата 25.7.2005, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 3
Всего: 43



Вопрос не ясен. Если операция выбора малого объекта уже осуществленна, то в чем тогда проблема?
PM ICQ   Вверх
Ravend
Дата 25.7.2005, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 19.7.2005

Репутация: нет
Всего: 1



Да в том то и дело что ещё не осуществлена. Выбор должен происходить даже если клик произошел в никуда, представьте себе при масштабировании объекты уменьшились до размера точек, требуется при клике привязывать (смещать) курсор (обрабатываемые координаты) к ближайшему объекту (для упрощения обрабатываем простые объекты, кубы, сферы)
PM MAIL   Вверх
gepard
Дата 25.7.2005, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 8
Всего: 40



Просто надо поставить ограничение на уменьшение размера Bounding Box'а и всё. Пусть он не будет скажем меньше чем 0,5 0,5 0,5. Вполне достаточно.


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
Ravend
Дата 25.7.2005, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 19.7.2005

Репутация: нет
Всего: 1



Ну это косвенный выход из положения.
Хотелось именно имея массив координат объектов в 3D найти тот объект чьи координаты в 2D проекции наиболее близко расположены к курсору мыши.

Как я представляю нужно из имеющейся 3D матрицы объектов учитывая масштабирование и поворот сцены создать 2D проекцию, что собственно и делает OpenGL но не выводить на экран, а получить некий массив, обрабатывая который можно найти искомый объект.

PM MAIL   Вверх
gepard
Дата 25.7.2005, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 8
Всего: 40



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


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
Ravend
Дата 25.7.2005, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 19.7.2005

Репутация: нет
Всего: 1



Это Вы говорите об уже сформированном изображении, но ведь у нас есть все составляющие, массив координат объектов, углы поворота, масштаб, из этих данных можно получить искомые данные. А распознавание образов нам тут и не нужно.
PM MAIL   Вверх
gepard
Дата 26.7.2005, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 8
Всего: 40



Я уже изложил свою точку зрения.


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.1352 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.