Ogre3D Intermediate Tutorials / Промежуточные туториалы Ogre3D: Intermediate Tutorial 4: Volume Selection and Basic Manual Objects
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Делается это очень просто. proVIDec 01.10.11 в 08:24 Сделать это на самом деле очень легко. Mingun 01.10.11 в 08:48 |
|
|
Найдите конструктор SelectionBox и добавьте туда следующий код: proVIDec 01.10.11 в 08:25 |
||
|
Первая функция устанавливает очередь визуализации для объекта такой же, как у очереди оверлеев. Mingun 01.10.11 в 08:55 |
||
|
Следующие две функции устанавливают единичные матрицы для матриц проекции и вида. Mingun 01.10.11 в 08:56 |
||
|
Матрицы проекции и вида используются многими системами визуализации (такими, как OpenGL и DirectX) для определения того, где объекты располагаются в мире. Mingun 01.10.11 в 08:59 |
||
|
Так как Ogre абстрагирует нас от этого, мы не будем вникать в какие-либо детали о том, что это за матрицы или что они делают. Mingun 01.10.11 в 09:28 |
||
|
Вместо этого все, что вы должны знать - установив единичные матрицы для матриц проекции и вида, как мы имеем здесь, мы по сути создадим 2D объект (прим. пер.: вынужден не согласится с автором, так как без знания, что же это за матрицы и что они делают, в 3D графике далеко не уедешь. Поэтому, если вы этого не знаете, бегом хотя бы на википедию). Mingun 01.10.11 в 09:33 |
||
|
При определении этого объекта система координат немного меняется. Mingun 01.10.11 в 09:36 |
||
|
Мы больше не имеем дела с осью Z (если вас спросят про ось Z, установите значение в -1). Mingun 01.10.11 в 09:37 |
||
|
Теперь мы имеем новую систему координат, с осями X и Y от -1 до 1 включительно (т.е., в математической нотации, [-1; 1]). Mingun 01.10.11 в 09:38 |
||
|
Наконец, мы устанавливаем флаги запроса для объекта в 0, что предотвращает включение прямоугольника выделения в результаты запроса (о запросах ниже). Mingun 01.10.11 в 09:49 |
||
|
Теперь, когда объект настроен, нам нужно, собственно, создать прямоугольник. Mingun 01.10.11 в 09:50 |
||
|
У нас имеется одно маленькое препятствие, прежде чем мы начнем. Мы собираемся вызывать эту функцию с координатами мыши. Mingun 01.10.11 в 09:52 |
||
|
Так-то оно так, но мы получим число в диапазоне [0; 1] для x и у-координат, а нам нужно преобразовать его в число в диапазоне [-1; 1]. Mingun 01.10.11 в 09:54 |
||
|
Чтобы еще больше усложнить задачу, координата y также должна быть инвертирована. Mingun 01.10.11 в 09:58 |
||
|
Курсор мыши в CeGUI определяет верх экрана как 0, а низ как 1. proVIDec 01.10.11 в 09:33 Курсор мыши в CEGUI определяет верхнюю границу экрана как 0, а нижнюю - как 1. Mingun 01.10.11 в 09:59 |
||
|
В нашей новой системе координат, верх это +1, а низ -1. proVIDec 01.10.11 в 09:32 В новой системе координат верх экрана это +1, а низ это -1. Mingun 01.10.11 в 10:00 |
||
|
К счастью эта проблема решается легко. proVIDec 01.10.11 в 09:35 К счастью, несколько быстрых преобразований позаботятся об этой проблеме. Mingun 01.10.11 в 10:01 |
||
|
Найдите функцию setCorners и добавьте в нее следующее: proVIDec 01.10.11 в 09:25 Найдите функцию setCorners() и добавьте туда следующее: Mingun 01.10.11 в 10:02 |
||
|
Теперь позиции представлены в новой системе координат. Mingun 01.10.11 в 10:03 |
||
|
Далее мы должны собственно создать объект. Mingun 01.10.11 в 10:04 |
||
|
Чтобы сделать это, сперва вызовем метод begin(). Mingun 01.10.11 в 10:04 |
||
|
Он принимает два параметра, имя материала, используемого этой секцией объекта и операцию визуализации, используемую для его рисования. Mingun 01.10.11 в 10:06 |
||
|
Так как мы не помещаем текстуру на него, мы оставим материал пустым (прим. пер.: в оригинале используется пустая строка "". Однако правильнее передать объект StringUtil::BLANK, который специально для этого и предназначен). Mingun 01.10.11 в 10:07 |
||
|
Второй параметр - операция визуализации RenderOperation. Mingun 01.10.11 в 10:08 |
||
|
Мы можем отрисовать сетку, используя точки, линии или треугольники. Mingun 01.10.11 в 10:09 |
||
|
Мы бы использовали треугольники, если бы отрисовывали полную сетку, но так как мы хотим пустой прямоугольник, мы будем использовать полосу линий. Mingun 01.10.11 в 10:11 |
||
|
Полоса линий подразумевает рисование линии до каждой вершины от предыдущей определенной вами вершины. Mingun 01.10.11 в 10:14 |
||
|
Так что для создания нашего прямоугольника мы должны определить 5 точек (первая и последняя одинаковы для замыкания прямоугольника): Mingun 01.10.11 в 10:15 |
||
|
Обратите внимание, что поскольку мы будем вызывать этот код много раз, мы добавили вызов clear() в начало для удаления предыдущего прямоугольника, прежде чем перерисовывать его. Mingun 01.10.11 в 11:12 |
||
|
При определении объекта ManualObject вы можете вызывать begin()/end() несколько раз для создания нескольких частей сеток (sub-mesh) (которые могут иметь различные материалы/операции визуализации). Mingun 01.10.11 в 11:24 |
||
|
Заметьте, что мы также устанавливаем параметр Z в -1, как как мы пытаемся определить 2D объект, который не использует эту ось. Mingun 01.10.11 в 11:27 |
||
|
Установка его в -1 гарантирует, что мы не окажемся выше, или позади, камеры при отрисовке. Mingun 01.10.11 в 11:30 |
||
|
Последняя вещь, которую мы должны сделать, это установка ограничивающего параллелепипеда для этого объекта. Mingun 01.10.11 в 11:36 |
+3 | |
|
Многие менеджеры сцен отбрасывают объекты, которые находятся вне экрана. Mingun 01.10.11 в 11:44 |
+2 | |
|
Даже при том, что мы в сущности создали 2D объект, Ogre все же 3D-движок и обрабатывает наш 2D объект, как будто он находится в 3D пространстве. Mingun 01.10.11 в 11:48 |
||
|
Это означает, что если мы создадим этот объект и присоединим его к узлу сцены (как мы и сделаем в следующем разделе), он пропадет из виду, как только мы отвернемся. Mingun 01.10.11 в 11:51 |
||
|
Чтобы исправить это, мы устанавливаем ограничивающий параллелепипед объекта в бесконечность, таким образом камера всегда будет внутри него: Mingun 01.10.11 в 11:52 |
||
|
Убедитесь, что вы добавили этот код после вызова clear(). Mingun 01.10.11 в 11:56 |
||
|
Каждый раз при вызове ManualObject::clear() ограничивающий параллелепипед сбрасывается, поэтому будьте осторожны, если вы создаете другой ManualObject, который часто очищается, потому что ограничивающий параллелепипед надо устанавливать каждый раз, когда вы пересоздаете его. Mingun 01.10.11 в 12:03 |
||
|
Это все, что нам нужно было сделать в классе SelectionBox. proVIDec 01.10.11 в 08:31 |
||
|
Перед тем, как продолжать, убедитесь, что код компилируется, однако ничего нового программа пока делать не будет proVIDec 01.10.11 в 08:31 |
||
|
ОБЪЕМНОЕ ВЫДЕЛЕНИЕ Mingun 01.10.11 в 12:24 МАСШТАБНОЕ ВЫДЕЛЕНИЕ proVIDec 02.10.11 в 13:04 ВЫДЕЛЕНИЕ ОБЪЕМА Mingun 03.10.11 в 13:56 ВЫДЕЛЕНИЕ В ПРОСТРАНСТВЕ Mingun 03.10.11 в 13:58 |
+8 | |
|
НАСТРОЙКА proVIDec 01.10.11 в 08:25 |
||
|
Прежде, чем мы перейдем к коду выделения, мы должны настроить несколько вещей. Mingun 01.10.11 в 12:26 |
||
|
Прежде всего включите SelectionBox.h в наш файл IntermediateTutorial4.h, чтобы мы могли использовать его; также мы должны объявить переменную-указатель для рамки выделения, поместив ее в раздел protected класса IntermediateTutorial4. Mingun 01.10.11 в 12:33 |
||
|
Теперь, когда все настроено, мы должны создать экземпляр класса SelectionBox и попросить менеджер сцены создать для нас запрос из объема. Mingun 01.10.11 в 12:39 |
||
|
Добавьте следующий код в конец createScene(), так как в этом случае мы точно знаем, что менеджер сцены был инициализирован. Mingun 01.10.11 в 12:43 |
||
|
Во-вторых, мы должны убедиться, что слушатель кадров подчищает после себя, когда мы закончим. Mingun 01.10.11 в 12:45 |
||
|
Добавьте следующий код в деструктор IntermediateTutorial4: proVIDec 01.10.11 в 08:25 Добавьте следующий код в ~IntermediateTutorial4: Mingun 01.10.11 в 12:46 |
