Ogre3D Intermediate Tutorials / Промежуточные туториалы Ogre3D: Intermediate Tutorial 4: Volume Selection and Basic Manual Objects
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Заметьте, что мы предоставляем менеджеру сцены подчистить запрос за нас вместо прямого его удаления. Mingun 01.10.11 в 12:48 |
|
|
ОБРАБОТЧИКИ МЫШИ Mingun 01.10.11 в 12:48 |
||
|
Возможность, которую мы пытаемся реализовать - выделение объема. Mingun 02.10.11 в 16:41 |
||
|
Это означает, что когда пользователь нажимает кнопку мыши и проводит курсор вдоль экрана, будет рисоваться прямоугольник. proVIDec 02.10.11 в 12:33 |
||
|
Когда кнопку мыши отпустят, все объекты, находящиеся в прямоугольнике, будут выделены. proVIDec 02.10.11 в 12:36 |
||
|
Первое, что нам нужно, это знать, когда нажата мышь. proVIDec 02.10.11 в 12:35 Первое, что мы должны сделать - обработать нажатие на кнопку мыши. Mingun 03.10.11 в 14:06 |
||
|
Мы должны сохранить начальную позицию и сделать SelectionBox видимым. Mingun 02.10.11 в 16:38 |
||
|
Найдите функцию mousePressed и добавьте в нее следующий код: proVIDec 01.10.11 в 09:41 |
||
|
Заметим, что мы используем x и y от CEGUI::MouseCursor, а не от OIS. proVIDec 02.10.11 в 12:38 Обратите внимание, что мы используем координаты x и y от CEGUI::MouseCursor, а не от координат мыши OIS-а. Mingun 02.10.11 в 16:44 |
||
|
Это потому что иногда OIS передает координаты, не соответствующие тому, что отображает CeGUI. proVIDec 02.10.11 в 15:17 Это потому, что иногда OIS думает, что мышь находится в другом месте, чем ее отображает CEGUI (прим. пер.: если это баг, то он уже мог быть исправлен, поэтому не поленитесь и проверьте). Mingun 02.10.11 в 16:47 |
||
|
Чтобы убедиться, что мы оперируем тем же, что и видит пользователь, мы будем использовать координаты мыши, которую предоставляет CeGUI. proVIDec 02.10.11 в 15:18 Чтобы убедиться, что мы синхронизированы с тем, что видит пользователь, мы используем координаты мыши, предоставляемые CEGUI. Mingun 02.10.11 в 16:49 |
+2 | |
|
Следующее, что мы должны сделать - остановить отображение прямоугольника выделения и выполнить запрос на выделение, когда пользователь отпускает кнопку мыши. Mingun 02.10.11 в 16:52 |
||
|
Добавьте следующий код в mouseReleased: proVIDec 02.10.11 в 12:39 |
||
|
Наконец, нужно каждый раз, как двигается мышь, обновлять координаты прямоугольника. proVIDec 02.10.11 в 15:21 Наконец, каждый раз при движении мыши нужно обновлять координаты углов прямоугольника: Mingun 02.10.11 в 16:58 Ко всему прочему, каждый раз при движении мыши нужно обновлять координаты углов прямоугольника: Mingun 02.10.11 в 16:59 |
+1 | |
|
Мы корректируем вектор mStop каждый раз при движении мыши, поэтому мы можем просто использовать его в функции-члене setCorners(). Mingun 02.10.11 в 17:02 Мы корректируем вектор mStop каждый раз при движении мыши, поэтому мы можем просто использовать его в функции-члене setCorners(). Mingun 03.10.11 в 14:17 |
+1 | |
|
Скомпилируйте и запустите приложение. Теперь вы можете рисовать прямоугольник с помощью мыши. proVIDec 01.10.11 в 09:42 |
+2 | |
|
PLANEBOUNDEDVOLUMELISTSCENEQUERY proVIDec 16.07.11 в 14:08 |
||
|
Теперь, когда область выделения отображается корректно, нам нужно разобраться с масштабным выделением. proVIDec 01.10.11 в 09:44 Теперь, когда рамка выделения отображается корректно, нам нужно выполнить само объемное выделение. Mingun 02.10.11 в 17:11 |
||
|
Найдите функцию performSelection() и добавьте следующий код: Mingun 02.10.11 в 17:15 |
||
|
В этом куске кода мы заносим параметры векторов в переменные left, right, top и bottom. Mingun 02.10.11 в 17:16 |
||
|
Выражение if гарантирует, что меньшие значения окажутся слева и сверху. Mingun 02.10.11 в 17:17 |
||
|
(Если прямоугольник рисуется "наоборот", т.е. из нижнего-правого к верхнему-левому углу, то мы выполняем этот обмен.) Mingun 02.10.11 в 17:19 |
||
|
Далее, мы должны проверить и посмотреть, насколько большую область охватывает прямоугольник. Mingun 02.10.11 в 17:21 |
||
|
Если прямоугольник очень маленький, наш метод создания ограниченного плоскостью объема не поможет и мы закончим тем, что выберем слишком много или слишком мало объектов. Mingun 02.10.11 в 17:23 |
||
|
Если прямоугольник будет меньше, чем определенный процент от экрана, мы просто выйдем из функции без выполнения выделения. Mingun 02.10.11 в 17:24 |
||
|
Порог 0.0001 для отмены запроса выбран произвольно, вы должны поиграться с этим значением в своей собственной программе. Mingun 02.10.11 в 17:26 |
+1 | |
|
Также, в реальном приложении вы вероятно должны найти центр прямоугольника и выполнить стандартный запрос RaySceneQuery вместо игнорирования попытки выделения. Mingun 02.10.11 в 17:30 |
||
|
Теперь мы добрались до сути функции и должны выполнить требуемый запрос. Mingun 02.10.11 в 17:31 |
||
|
Запросы PlaneBoundedVolumeQuerie используют плоскости для выделения области и выборки любых находящихся в ней объектов. Mingun 02.10.11 в 17:32 |
||
|
Для этого примера мы создадим область, отгороженную пятью плоскостями, смотрящими вовнутрь. Mingun 02.10.11 в 17:34 |
||
|
Для создания этих плоскостей из нашего прямоугольника мы создаем 4 луча, по одному на каждый угол. Mingun 02.10.11 в 17:35 |
||
|
Как только мы получим эти четыре луча, мы возьмем точки на лучах для создания плоскостей: Mingun 02.10.11 в 17:37 |
||
|
Теперь создадим плоскости. proVIDec 02.10.11 в 12:49 |
||
|
Обратите внимание, что мы выбираем точки в 100 единицах от начала луча. Mingun 02.10.11 в 17:39 |
||
|
Это значение выбрано произвольно, просто для красоты. Мы могли бы использовать 2 вместо 100. Mingun 02.10.11 в 17:41 |
||
|
Единственная точка, которая имеет здесь значение, это определяющая переднюю плоскость, которая начинается в 3 единицах перед камерой. Mingun 02.10.11 в 17:43 |
||
|
Эти плоскости теперь определяют "открытый параллелепипед", который простирается в бесконечность перед камерой. Mingun 02.10.11 в 17:45 |
||
|
Вы можете думать о прямоугольнике, который мы нарисовали мышью, как о конечной точке параллелепипеда прямо перед камерой. Mingun 02.10.11 в 17:46 |
||
|
Теперь, когда мы имеет плоскости, мы должны выполнить запрос: Mingun 02.10.11 в 17:47 |
||
|
Наконец, мы должны обработать результаты запроса. Mingun 02.10.11 в 17:47 |
||
|
Вначале мы снимаем выделение со всех объектов, выделенных до этого, затем мы выделяем все объекты, которые были найдены запросом. Mingun 02.10.11 в 17:49 |
||
|
Функции deselectObjects() и selectObject() уже были написаны для вас, так как мы рассмотрели их в предыдущем уроке: Mingun 02.10.11 в 17:52 |
||
|
Это все, что мы должны были сделать для запроса. Mingun 02.10.11 в 17:53 |
||
|
Обратите внимание, что мы также можем использовать флаги запроса на запросах объема, даже при том, что мы не использовали их в этом уроке. Mingun 02.10.11 в 17:55 |
||
|
Смотрите предыдущий урок, чтобы узнать, как использовать флаги запроса. Mingun 02.10.11 в 17:55 |
||
|
Теперь, пока не забыли, нам нужно заполнить функции selectObject() и deselectObjects(). Mingun 02.10.11 в 17:56 |
||
|
Скомпилируйте и запустите приложение. proVIDec 01.10.11 в 08:26 |
||
|
Теперь вы можете выделять объекты в некотором объеме сцены! Mingun 02.10.11 в 17:58 |
||
|
ПОСЛЕДНЕЕ ЗАМЕЧАНИЕ ОБ ОГРАНИЧИВАЮЩИХ ПАРАЛЛЕЛЕПИПЕДАХ Mingun 02.10.11 в 17:59 |
||
|
Как вы заметили в этом уроке и в предыдущих двух уроках, выделение в Ogre зависит от ограничивающего параллелепипеда рассматриваемых объектов, а не от их сетки. Mingun 02.10.11 в 18:03 |
