6.2.3. Фильтрациястолкновений
Фильтрация столкновений позволяет предотвратить столкновения между определенными фигурами. Например, вы создаете персонажа, который едет на велосипеде. Вам необходимо, чтобы велосипед и персонаж взаимодействовали с ландшафтом, но при этом велосипед и персонаж не взаимодействовали между собой (так как они пересекаются). Для таких случаев Box2D поддерживает фильтрацию столкновений при помощи категорий и групп.
Box2D поддерживает 16 категорий взаимодействия. Для каждой фигуры, можно указать категорию, которой она принадлежит. Можно также указать с какими другими категориями может взаимодействовать эта фигура. Например, в многопользовательской игре вам необходимо указать, что все игроки не взаимодействуют друг с другом, и что монстры не взаимодействуют друг с другом, но при этом необходимо, чтобы игроки и монстры взаимодействовали друг с другом. Это можно осуществить при помощи "маски битов" (maskBits). Например:
playerShapeDef.filter.categoryBits = 0x0002;
monsterShapeDef.filter.categoryBits = 0x0004;
playerShape.filter.maskBits = 0x0004; monsterShapeDef.filter.maskBits = 0x0002;
Группы взаимодействия позволяют указать индекс группы. Все фигуры с одинаковым индексом группы могут всегда взаимодействовать (если индекс положительный) или никогда не взаимодействовать (если индекс отрицательный). Индексы групп обычно используются для вещей которые как-нибудь связаны, подобно частям велосипеда. В следующем примере, shapel и shape2 всегда взаимодействуют, a shape3 и shape4 -никогда.
shapelDef.filter.grouplndex = 2;
shape2Def.filter.grouplndex = 2;
shape3Def.filter.grouplndex = -8; shape4Def.filter.grouplndex = -8;
Столкновения между фигурами различных групп фильтруются в соответствии с категориями и "маскирующими" битами. Другими словами, группы имеют более высокий приоритет по сравнению с категориями. Следует отметить, что в Box2D происходит дополнительная фильтрация столкновений:
Фигуры статичных тел никогда не взаимодействуют друг с другом.
Фигуры одного и того же тела никогда не взаимодействуют друг с другом.
При желании можно указать будут ли сталкиваться фигуры соединенных тел. Иногда необходимо изменить фильтрацию столкновений после того как фигура была создана. Можно получить и установить структуру b2FilterData существующей фигуры, используя методы b2Shape: :GetFilterData и b2Shape: :SetFilterData. Box2D кэширует результаты фильтрования, поэтому, после изменения фильтрации, нужно вызвать b2World::Refilter.
6.2.4. Сенсоры
Иногда требуется узнать когда пересеклись две фигуры и при этом не требуется обрабатывать столкновение между ними. Эта задача решается при помощи сенсоров. Сенсор это фигура, которая лишь обнаруживает столкновения с другими телами и при этом не влияет на них.
Можно пометить любую фигуру (статичную и динамичную) как сенсор. При этом если тело имеет несколько фигур, то любые из них могут быть сенсорами.
myShapeDef.isSensor = true;
6.2.5. ОпределениеОкружности
b2CircleDef это расширение b2ShapeDef путем добавления полей радиуса и локальной позиции.
b2CircleDef def; def.radius = 1.5f; def.localPosition.Set(l.Of, 0. Of) ;
6.2.6. ОпределениеПолигона
Структура b2PolyDef используется для создания выпуклых полигонов. Создание полигонов имеет нюансы, поэтому внимательно читайте текст. Максимальное
число вершин определяется константой b2_maxPoiygonVertices, по умолчанию равной 8. Если необходимо использовать большее число вершин, то надо изменить константу
b2_maxPolygonVertices В файле b2Settings.h .
При построении полигона необходимо указать число вершин, которое будет использоваться. Координаты вершин должны быть указаны в порядке против часовой стрелки относительно оси z правосторонней системы координат. Но на экране это может выглядеть как по часовой стрелке в зависимости от экранных координат.
Полигоны должны быть выпуклыми и грани полигона не должны пересекаться. Другими словами, каждая вершина должна выглядывать наружу. Box2D автоматически замкнёт контур полигона.
Convex Concave
Пример определения полигона в виде треугольника:
b2PolygonDef triangleDef; triangleDef.vertexCount = 3; triangleDef.vertices[0].Set(-1.0f, O.Of); triangleDef.vertices[l].Set(1.0f, 0.Of); triangleDef.vertices[2].Set(O.Of, 2.Of);
Вершины задаются в координатной системе тела. Если необходимо сместить полигон относительно тела, то надо только сместить позиции вершин. Для удобства, имеются функции инициализации полигонов в виде боксов. Можно создать как ААВВ с центром в позиции тела, так и повернутый бокс со смещением относительно позиции тела.
b2PolygonDef alignedBoxDef; float32 hx = l.Of; // половина ширины float32 hy = 2.Of; // половина высоты alignedBoxDef.SetAsBox(hx, hy) ;
b2PolygonDef orientedBoxDef; b2Vec2 center(-1.5f, O.Of); float32 angle = 0.5f * b2_pi; orientedBoxDef.SetAsBox(hx, hy, center, angle);
6.3. Фабрикафигур
Для того чтобы создать фигуру надо заполнить определение фигуры и передать его методу-фабрике тела.
b2CircleDef circleDef; circleDef.radius = 3.0f; circleDef.density = 2.5f;
b2Shape* myShape = myBody->CreateShape(ScircleDef) ; [если необходимо, то используем указатель на фигуру]