-
Notifications
You must be signed in to change notification settings - Fork 54
/
interaction-groups.ts
43 lines (41 loc) 路 1.69 KB
/
interaction-groups.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { InteractionGroups } from "@dimforge/rapier3d-compat";
/**
* Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
* properties of RigidBody or Collider components. The first argument represents a list of
* groups the entity is in (expressed as numbers from 0 to 15). The second argument is a list
* of groups that will be filtered against. When it is omitted, all groups are filtered against.
*
* @example
* A RigidBody that is member of group 0 and will collide with everything from groups 0 and 1:
*
* ```tsx
* <RigidBody collisionGroups={interactionGroups([0], [0, 1])} />
* ```
*
* A RigidBody that is member of groups 0 and 1 and will collide with everything else:
*
* ```tsx
* <RigidBody collisionGroups={interactionGroups([0, 1])} />
* ```
*
* A RigidBody that is member of groups 0 and 1 and will not collide with anything:
*
* ```tsx
* <RigidBody collisionGroups={interactionGroups([0, 1], [])} />
* ```
*
* Please note that Rapier needs interaction filters to evaluate to true between _both_ colliding
* entities for collision events to trigger.
*
* @param memberships Groups the collider is a member of. (Values can range from 0 to 15.)
* @param filters Groups the interaction group should filter against. (Values can range from 0 to 15.)
* @returns An InteractionGroup bitmask.
*/
export const interactionGroups = (
memberships: number | number[],
filters?: number | number[]
): InteractionGroups =>
(bitmask(memberships) << 16) +
(filters !== undefined ? bitmask(filters) : 0b1111_1111_1111_1111);
const bitmask = (groups: number | number[]): InteractionGroups =>
[groups].flat().reduce((acc, layer) => acc | (1 << layer), 0);