Specific Collision Properties

50 views
Skip to first unread message

Alphenex

unread,
Jun 30, 2023, 7:52:31 AM6/30/23
to ode-users
Hello, sorry for deleting my previous stuff about working with different units. Thanks to whoever replied :)

Is there a way for me to create a system where I can apply correct 'bounce, friction etc' to my objects.
So for example, GeometryA is not slippery and it is bouncey. GeometryB though is not bouncey neither slippery. How can I apply collisions in that way?

I know how to set bounce level etc but I don't quite understand how I can set it so it is different for every object. I would appreciate some help.

Vaillancourt

unread,
Jun 30, 2023, 8:42:57 PM6/30/23
to ode-users
Hello Alphenex


> So for example, GeometryA is not slippery and it is bouncey. GeometryB though is not bouncey neither slippery

That's not exactly how it works. A rubber tire will be slippery on ice, but not on asphalt. A ball will bounce on concrete but not on water. So collision parameters are not specific to a geometry, instead they are specific to a geometry pair.

So, by "I know how to set bounce level etc", I suppose you imply that you know that when a contact occurs, you create a contact joint and supply the parameters to the `surface` of the `dContact` object.

You need to decide what values you supply to this based on what geom1 and geom2 are.

You could piggy back on the category bits to determine which type of object is (see `dGeomSetCategoryBits`).

So you would first need to compose a registry of "surface pairs" parameters

(note that this is all pseudo-code)

enum CollisionCategory
  asphalt = 0
  rubber = 1
  ice = 2
 
map<uint64_t, SurfaceParams> surface_params
surface_params[ashpalt << 32 | asphalt] = { surface params when asphalt and ashpalt contact }
surface_params[ashpalt << 32 | rubber] = { surface params when asphalt and rubber contact }
surface_params[ashpalt << 32 | ice] = { surface params when asphalt and ice contact }
surface_params[rubber << 32 | rubber] = { surface params when rubber and rubber contact }
surface_params[rubber << 32 | ice] = { surface params when rubber and ice contact }
surface_params[ice << 32 | ice] = { surface params when ice and ice contact }

then when you get a contact

vector<uint32> catBits
catBits.push_back( dGeomGetCategoryBits(geom1Id))
catBits.push_back( dGeomGetCategoryBits(geom2Id))

sort(catBits)

SurfaceParams& desiredParams = surface_params.at(catBits[0] << 32 | catBits[1])

then you apply the surface parameters to the new contact joint you create.

This may become unwieldy at some point because ODE uses the colcat bits to do quick check rejections, so you may want to use this just for that. Then you need to come up with a secondary and parallel approach to apply "materials" to your geoms.

Instead of using the category bits, you will supply data to each of your objects using the "custom data" approach. Using `dGeomSetData` and `dGeomGetData`, you can supply a pointer to your own class/objects where you store the material/surface information for this geom.

The infrastructure may be the same as I described above, it's just that instead of storing the data in ODE's pre-defined variables, you do it in your own:

class MyDataClass
  public:
    uint32 surfaceBits_ {}

So when you're about to create the contact joint,

MyDataClass* myDataClassGeom1 = reinterpret_cast<MyDataClass*>(dGeomGetData(geom1Id));
MyDataClass* myDataClassGeom2 = reinterpret_cast<MyDataClass*>(dGeomGetData(geom1Id));

vector<uint32> catBits
catBits.push_back(  myDataClassGeom1->surfaceBits_ )
catBits.push_back(  myDataClassGeom2->surfaceBits_ )
...

(the process is essentially the same)

This all may be more or less complicated depending on your infrastructure, how you load your data and your needs.

Hope it helps!

Vaillancourt
Reply all
Reply to author
Forward
0 new messages