Как работают короткие int-ориентированные маски в C ++ (например, те в Пуле)?
CollisionFilterGroups {
DefaultFilter = 1,
StaticFilter = 2,
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
CharacterFilter = 32,
AllFilter = -1
}
И увидеть, что все значения являются степенями 2 и я знать, что:
short — целое число со знаком, для хранения которого требуется 2 байта, от –32 768 до +32 767.
Но как создать свои собственные группы: как рассчитать пересечения маски?
Например, как создать в дополнение к CollisionFilterGroups что-то вроде:
MyCollisionFilterGroups {
Cubes= ?,
Boxes= ?,
Spheres= ?
}
куда
Ваш вопрос неясен, но я думаю, что вы хотите установить биты категорий и маски для объектов в вашей симуляции:
MyCollisionFilterGroups {
Plane= 64,
Box= 128,
Sphere= 256
}
Плоскость, биты категории = Плоскость, Маска = 0
Коробка, биты категории = Коробка, маска = Коробка + Сфера (или Коробка | Сфера)
Сфера, биты категории = Сфера, маска = Коробка
В двух словах, создайте степень двойки для каждой группы фильтров, установите маску категории для каждого объекта на перечисление группы и установите ее маску на перечисление типов объектов, с которыми вы хотите, чтобы она сталкивалась (или 0, чтобы столкнуться ни с чем) ,
По сути, если это степень двойки, это означает, что в двоичном представлении есть только один 1 бит, а остальные равны 0, например: 1 = 1, 2 = 10, 4 = 100, 8 = 1000, 16 = 10000 и тд. Теперь предположим, что a = 1, b = 2, c = 4, d = 8, e = 16, f = 32. если у вас есть число, и вы хотите увидеть, есть ли у него a и e, вы создаете маску, подобную этой : a | b (или) … это приведет к двоичному представлению 10001.
Допустим, число, которое вы хотите проверить для a и e, равно X. Следующее утверждение верно только в том случае, если X содержит a и e: X&(a | e) == X, то есть X и (a или e) равно X.
Для первого примера X — 11001, то есть содержит a и e. 11001 & 10001 будет 10001, так что это правда, поэтому вы обнаружили, что X содержит a и e.
Второй пример: X равен 100111, то есть содержит a, но не содержит e. когда вы «и» с помощью | e (10001), это приведет к 000001, который не равен X, следовательно, X не содержит.
Теперь для инициализации, если вы хотите, чтобы число содержало a, c, e, напишите: X = a | c | e
Все сводится к двоичному представлению чисел. В написанном вами примере есть также -1, который в двоичном представлении равен 1111..11, что означает, что он охватывает все.
Надеюсь это поможет
Не уверен, как работает конкретная пуля, но идея такова:
Каждый объект имеет флаг группы столкновений и маску столкновений.
Группа столкновений — это классификатор вашего объекта (что это за объект).
Маска столкновения — это все группы (классификаторы), с которыми сталкивается ваш объект (обычно он начинается с 0xffff, что означает, что он сталкивается со всем)
В тесте на столкновение это выглядит так:
if( obj->group & otherObj->mask
&&
obj->mask & otherObj->group )
..check collision..
Если вы хотите создать новые группы (я не знаю, как работает bullet или разрешить это), создать группу с одним установленным битом, а он еще не установлен (те, которые вы показываете в своем посте), я не хотел бы писать его Интс, это путать, я предпочитаю биты сдвиги:
DefaultFilter = 1 equals (1<<0)
StaticFilter = 2, equals (1<<1)
KinematicFilter = 4, equals (1<<2)
DebrisFilter = 8, equals (1<<3)
SensorTrigger = 16, equals (1<<4)
CharacterFilter = 32, equals (1<<5)
AnewGroup_Box = (1<<6),
AnewGroup_Sphere = (1<<7)
До количества бит в коротком (в основном 16).
Чтобы установить, с какими группами сталкивается ваш объект (не группа), просто объедините группы в маске:
myObj->mask = AnewGroup_Box | StaticFilter | DebrisFilter; // groups obj will collide
Я не уверен, как работает Пуля, ты ..
Надеюсь, это поможет, поправьте меня, если я ошибаюсь.