Ogre3D Intermediate Tutorials / Промежуточные туториалы Ogre3D: Intermediate Tutorial 3: Mouse Picking (3D Object Selection) and SceneQuery Masks (Part 2 of 2)
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
RaySceneQueryResult возвращает итератор структуры RaySceneQueryResultEntry. Taredd 27.09.11 в 07:29 |
|
|
Эта структура содержит три переменных. Taredd 26.09.11 в 21:37 |
||
|
Переменная distance показывает как далеко находится объект в направлении луча. Taredd 27.09.11 в 07:32 |
||
|
Одна из двух оставшихся переменных будет не нулевой. Taredd 27.09.11 в 07:32 |
||
|
Переменная movable будет содержать MovableObject(перемещаемый объект) если Луч его пересекает. Taredd 27.09.11 в 07:33 |
||
|
WorldFragment будет содержать WorldFragment объекты, если он попал в фрагмент мира (например террайн). neutron 06.11.11 в 21:06 |
||
|
MovableObjects(Перемещаемые объекты) это практически любые объекты, которые вы будете добавлять в сцену(такие как Сущности, Источники Света и т.д.) Taredd 27.09.11 в 07:37 |
||
|
Посмотрите на дерево наследования на этой странице, чтобы узнать, какой тип объектов будет возвращен. oYASo 28.09.11 в 16:29 |
||
|
Обычно RaySceneQueries применяют для выбора и манипулирования либо MovableObject, по которому вы кликаете, либо SceneNode, к которому MovableObject присоединены. oYASo 28.09.11 в 16:31 |
||
|
Чтобы получить имя MovableObject (Перемещаемый объект), вызовите метод getName (получить имя). oYASo 28.09.11 в 16:33 |
||
|
Чтобы получить SceneNode (имя узла) или Node (узел), к которому присоединен объект, вызовите getParentSceneNode (получить родительский узел сцены) или getParentNode (получить родительский узел). oYASo 28.09.11 в 16:35 |
||
|
Переменная RaySceneQueryResultEntry будет равна NULL, если результат не является MovableObject (перемещаемый объект). oYASo 28.09.11 в 16:40 |
||
|
WorldFragment это различные фрагменты все вместе. neutron 06.11.11 в 21:25 |
||
|
Если установлен worldFragment, член RaySceneQueryResult, то это означает, что результатом будет являться часть мировой геометрии, созданной SceneManager (менеджер сцены). (анонимно) 28.09.11 в 21:47 |
||
|
Тип мирового фрагмента, который возвращается, является базовым в SceneManager. oYASo 28.09.11 в 21:50 |
||
|
Реализация WorldFragment структуры включает в себя fragmentType переменную, которая определяет тип мирового фрагмента. oYASo 28.09.11 в 21:53 |
||
|
На основе переменной fragmentType устанавливаются другие переменные (singleIntersection, planes, geometry ил renderOp). oYASo 28.09.11 в 21:55 |
||
|
В общем говоря, RaySceneQueries возвращает только WFT_SINGLE_INTERSECTION WorldFragments. oYASo 28.09.11 в 21:55 |
||
|
singleIntersection переменная является простым вектором Vector3, сообщающим о местоположении пересечения. oYASo 28.09.11 в 21:57 |
||
|
Другие типы мировых фрагментов выходят за рамки данного руководства. oYASo 28.09.11 в 21:57 |
||
|
Теперь давайте посмотрим на пример. oYASo 28.09.11 в 21:57 |
||
|
Допустим, мы хотим вывести список результатов после использования RaySceneQuery. oYASo 28.09.11 в 21:58 |
||
|
Следующий код сделает это. oYASo 28.09.11 в 21:59 |
||
|
(Предполагается, что объект fout является типом ofstream, уже созданным с помощью метода open). oYASo 28.09.11 в 22:00 |
||
|
Этот код выведет имена всех MovableObjects, которые пересечет луч, а также будут выведены местоположения этих пересечений на мировой геометрии (если они не будут удалены). oYASo 28.09.11 в 22:02 |
||
|
Обратите внимание, что иногда это может работать странным образом. oYASo 28.09.11 в 22:03 |
||
|
Например, если вы используете TerrainSceneManager, начало луча должно быть над ландшафтом, иначе пересечение не будет зарегистрировано. oYASo 28.09.11 в 22:07 |
||
|
Различные менеджеры сцены реализуют RaySceneQueries по-разному. neutron 06.11.11 в 21:27 |
||
|
Имейте в виду, экспериментируя с ним, когда вы используете его вместе с новым SceneManager. neutron 06.11.11 в 21:29 |
||
|
Теперь, если мы посмотрим на код нашей RaySceneQuery, то заметим что: мы не проходим по всем результатам! neutron 28.01.12 в 21:33 |
||
|
На самом деле мы смотрим только на первый результат, который (в случае TerrainSceneManager) является геометрией мира. wuffur 12.01.12 в 14:55 |
||
|
это плохо, так как мы не можем быть wuffur 12.01.12 в 16:40 Это плохо, имхо мы не можем быть уверены, что TerrainSceneManager всегда будет в первую очередь возвращать мир геометрии. neutron 28.01.12 в 21:34 |
||
|
Нам нужно перебрать результаты, чтобы убедиться, что мы нашли, что искали. neutron 28.01.12 в 21:36 |
||
|
С другой стороны, что мы хотим "подцепить" и перетаскивать объекты, которые уже были установлены. neutron 28.01.12 в 21:37 |
||
|
Если сейчас вы щелкните на объект, который был установлен ранее, программа игнорирует его и "робот" расположится за ним. neutron 28.01.12 в 21:55 |
||
|
Что же исправим это сейчас. neutron 28.01.12 в 21:38 |
||
|
Перейдем к функции mousePressed. proVIDec 04.11.11 в 05:14 |
||
|
Во первых мы хотим быть уверены, что когда кликаем, мы получаем первый объект вдоль луча. neutron 28.01.12 в 21:47 |
||
|
Чтобы сделать это, нам надо установить RaySceneQuery для сортировки по глубине. neutron 28.01.12 в 21:41 |
||
|
Найдите этот код в функции mousePressed: Taredd 26.09.11 в 21:38 |
||
|
И замените его на этот: Taredd 26.09.11 в 21:39 |
||
|
Теперь, когда мы возвращаемся результаты надлежащим образом, необходимо обновить код запроса результатов. neutron 28.01.12 в 21:43 |
||
|
Мы будем переписывать этот раздел, так что удалите этот код: neutron 28.01.12 в 21:44 |
||
|
Нам нужно сделать так, чтобы была возможность выбирать объекты, которые уже находятся на экране. proVIDec 05.11.11 в 05:09 |
||
|
Наша стратегия предполагает два варианта развития событий. proVIDec 05.11.11 в 05:04 |
||
|
Первое, если пользователь нажимает на объект, тогда создаем mCurrentObject эквивалентным его родительному SceneNode. proVIDec 05.11.11 в 05:04 |
||
|
Если пользователь нажимает не на объект (вместо этого нажимает на поверхность), поместить туда нового робота, как мы и делали раньше. proVIDec 05.11.11 в 05:07 |
||
|
Первое изменение состоит в том, что вместо ветвления if мы будем использовать цикл for: proVIDec 05.11.11 в 05:08 |
||
|
Проверим, если первое пересечение - MovableObject, если таким образом мы назначим mCurrentObject родителем SceneNode. neutron 28.01.12 в 21:53 |
||
|
Ну вот поймали все-таки. neutron 28.01.12 в 21:51 |
