Fix gimpact contacts handling

Issue #36 resolved
Piotr Piastucki created an issue

Hi,

It looks like ODE assumes that the contacts returned by Gimpact are ordered based on their importance, but it does not seem to be the case. At least not in ode4j.

In all these places the following piece of code is used to reduce the contacts returned by Gimpact to match the given limit (collision_trimesh_gimpact.cpp, collision_trimesh_ccylinder.cpp, collision_trimesh_plane.cpp, collision_trimesh_sphere.cpp):

GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
unsigned contactcount = trimeshcontacts.m_size;
unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK);
if (contactcount > maxcontacts)
{
    // !!! Sorting is missing here !!!
    contactcount = maxcontacts;
}

However, the contacts returned by Gimpact do not seem to be ordered by their importance and the result of such a brute-force trimming is quite random which leads to penetration for instance. It would be probably better to sort the contacts based on their significance before trimming the list. I fixed that by simply sorting the contacts according to their depths before trimming and the results are presented below. Some kind of contact clustering could possibly yield even better results, but sorting is simple to implement and works well.

Results (floor is also a trimesh, Gimpact reports up to 24 contacts while the limit is set to 3)

Before - https://vimeo.com/127967480

After - https://vimeo.com/127967557

Comments (8)

  1. Log in to comment