rapier.js icon indicating copy to clipboard operation
rapier.js copied to clipboard

setCollisionGroups help

Open Lightnet opened this issue 1 year ago • 1 comments

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/

Lightnet avatar Nov 28 '24 18:11 Lightnet

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;
}

pkpkTech avatar Mar 04 '25 13:03 pkpkTech