Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setCollisionGroups help #295

Open
Lightnet opened this issue Nov 28, 2024 · 1 comment
Open

setCollisionGroups help #295

Lightnet opened this issue Nov 28, 2024 · 1 comment

Comments

@Lightnet
Copy link

I am total lost how the collision filter works.

https://rapier.rs/docs/user_guides/javascript/colliders

Is there JavaScript easy call to convert to bit value?

function collisionGroup(id , groups=[]){
//...
return //bit value
}

let collisionid = collisionGroup(0 , [0, 2, 3]);

one reason is learning how to deal with the vehicle collisions.

There is tool for this site while learning it.

https://sbcode.net/threejs/physics-rapier-impulsejoint-motors/

@pkpkTech
Copy link

pkpkTech commented Mar 4, 2025

You may have already solved it but I'll answer anyway.

In Rapier's CollisionGroups, the upper 16 bits represent the group itself (membership), and the lower 16 bits represent the group of the collision targets (filter).
It's easier to understand when expressed in binary.

const GroupA = 0b0000_0000_0000_0001; // 1 in decimal
const GroupB = 0b0000_0000_0000_0010; // 2 in decimal
const GroupC = 0b0000_0000_0000_0100; // 4 in decimal

Note that there must be exactly one bit set to represent the membership.

To make A and B collide, set them as follows:

A.setCollisionGroups( (GroupA << 16) | GroupB ); // Binary: 0b0000_0000_0000_0001_0000_0000_0000_0010
B.setCollisionGroups( (GroupB << 16) | GroupA ); // Binary: 0b0000_0000_0000_0010_0000_0000_0000_0001

In the following example, A collides with A, B, and C,
but B and C only collide with GroupA.

A.setCollisionGroups( (GroupA << 16) | GroupA | GroupB | GroupC ); // Binary: 0b0000_0000_0000_0001_0000_0000_0000_0111
B.setCollisionGroups( (GroupB << 16) | GroupA ); // Binary: 0b0000_0000_0000_0010_0000_0000_0000_0001
C.setCollisionGroups( (GroupC << 16) | GroupA ); // Binary: 0b0000_0000_0000_0100_0000_0000_0000_0001

A straightforward implementation of a function to create a collision group looks like this:

function collisionGroup(membership, filter) {
    let value = membership << 16;
    
    // Collides with all if filter is not specified
    if (!Array.isArray(filter)) return (value | 0xffff);
    
    for (let i = 0; i < filter.length; i++)
        value = value | filter[i];
        
    return value;
}

However, the website you referred to uses 0 and 3 for membership.
This appears to determine which bit should be set, with the least significant bit having an index of 0.
floor = 0 means that the least significant bit is set, which results in 0b0000_0000_0000_0001,
axel = 3 means that the third bit is set, which results in 0b0000_0000_0000_0100.

A function implementing this logic would look like this:

function collisionGroup(membership, filter) {
    let value = (1 << membership) << 16;
    
    // Collides with all if filter is not specified
    if (!Array.isArray(filter)) return (value | 0xffff);
    
    for (let i = 0; i < filter.length; i++)
        value = value | (1 << filter[i]);
        
    return value;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants