Главная » Статьи » Учебник: теория

BitMask32 - для чего и как.

По умолчанию, каждый “from” объект, добавленный в CollisionTraverser, проверяется на коллизии с каждым узлом коллизий, находящимся в сцене. Тест на коллизии с видимой геометрией не проходится. Для базового приложения этого может быть достаточно, однако, часто может потребоваться больше контроля над коллизиями. Для этого в Панде предусмотрены маски коллизий. Каждый CollisionNode имеет две маски: "from" — используется, когда узел выступает в качестве "from" -объекта ( т. е. он добавлен в CollisionTraverser), и "into", которая используется если узел является "into" объектом (т. е. находится в графе сцены и проходит проверку на коллизии).

В дополнение, узлы GeomNodes также имеют маску "into", и могут выступать в роли "into"-объектов. (В то время как, только CollisionNode может быть "from"-объектом.)

Перед тем как будет проведена проверка коллизий для двух узлов, производится побитовое логическое сравнение их масок. В частности, "from"-маска from-объекта, и "into"-маска into-объекта. Если результат сравнения не равен 0, то происходит проверка коллизии, в противном случае, объекты игнорируются.

------------------------

Примечание переводчика: Небольшое пояснение для тех у кого фраза побитовое логическое сравнение вызывает макушечно-чесательный рефлекс. Ни для кого, думаю не секрет, что компьютер использует двоичную систему счисления, т. е. данные представляются в виде 0 и 1. Соответственно, и любое число может быть представлено в виде нулей и единиц. Так вот, для побитового сравнения используется это самое двоичное (битовое) представление. Каждый бит одного числа логически сравнивается с соответствующим битом второго числа. Логически — значит используется логическое «И» - конъюнкция.

Правила логического сравнения:

0 и 0 = 0

0 и 1 = 0

1 и 0 = 0

1 и 1 = 1

Пример: сравним два числа 6 и 2

6: 0110

2: 0010

0 и 0 = 0 ; 1 и 0 = 0 ; 1 и 1 = 1 ; 0 и 0 = 0

итого получаем число 0010, что в десятичном представлении является числом 2. Результат больше нуля и коллизия будет обсчитана

Сравним 6 с 1

6: 0110

1: 0001

0 и 0 = 0 ; 1 и 0 = 0 ; 1 и 0 = 0 ; 0 и 1 = 0

Результат 0000 т. е. просто 0 — коллизия не будет рассчитываться.

Запустив интерпретатор питона можно так же проверить результат — это делается с помощью оператора & т. е. пишем 6&2, нажимаем enter и получаем 2

------------------------

Маска назначается с помошью класса BitMask32, который является 32-хбитным целым числом с некоторыми дополнительными методами, позволяющими оперировать отдельными битами числа.

Маска from должна назначаться напрямую для node, а не для nodePath:

nodePath.node().setFromCollideMask(BitMask32(0x10))

Однако, маска into для удобства может быть назначена и для NodePath; это так же рекурсивно заменит маски для узлов того же уровня и подчинённых:

nodePath.setCollideMask(newMask, bitsToChange, nodeType)

Параметр newMask определяет маску, которая должна быть назначена. Остальные параметры опциональны; если они опущены, то каждому узлу, включённому в nodePath будет назначена маска newMask как маска into.

Параметр bitsToChange определяет набор битов для изменения, в случае, если менять предполагается не всю маску; нулевые биты в bitsToChange не будут модифицированы.

Параметр nodeType определяет тип узлов, чья маска будет модифицирована. Например, CollisionNode.getClassType() - изменены будут только CollisionNodes.

Примеры:

nodePath.setCollideMask(BitMask32(0x10))

Устанавливает маску into для nodePath, и всех его чайлдов, в значение 0x10 вне зависимости от предыдущего значения.

nodePath.setCollideMask(BitMask32(0x04), BitMask32(0xff))

Заменяет 8 нижних битов для nodePath и всех его чайлдов значением 0x04, оставляя неизменными верхние 24 бита.

Значения по умолчанию для CollisionNode могут быть получены с спомощью CollisionNode.getDefaultCollideMask(), а для GeomNode — с помощью GeomNode.getDefaultCollideMask().

Например, если вы хотите создать CollisionNode коллидящийся с видимой геометрией, можно попробовать сделать что-то вроде этого:

nodePath.node().setFromCollideMask(GeomNode.getDefaultCollideMask())

Функция NodePath.getCollideMask() возвращает объединение масок для узла и всех его чайлдов. Поскольку NodePath.setCollideMask() вызывается рекурсивно для чайлдов узла, то эффект следующего кода может кардинально отличаться от того, что казалось бы он делает на первый взгляд:

nodePath.setCollideMask(nodePath.getCollideMask())

Если вам нужно установить маску только для определённой части модели, то можно воспользоваться функцией find():

box=loader.loadModel("box")
box.find("**/Cube;+h").setCollideMask(BitMask32.bit(0))


Категория: Учебник: теория | Добавил: ninth (27.05.2009)
Просмотров: 5095 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Онлайн всего: 1
Гостей: 1
Пользователей: 0