Collisions between Collision World and static convex object

User avatar
jann.poppinga
Posts: 12
Joined: Wed Aug 26, 2009 3:32 pm

Collisions between Collision World and static convex object

Post by jann.poppinga »

Hi,

I have a btCollisionWorld consisting of a number of trimeshes. I want to put a sphere at a certain location and check whether it collides with any of the trimeshes. (The trimeshes collide with each other, but I want to ignore this.) If I understand correctly, the way to do this is to call convexSweepTest() with a tiny translation. I am using float for the coordinates, so I changed one coordinate to its nextafterf(x, numeric_limits<float>::max()). However, this seems not to be enough. I also tried using more steps (up to 500) or multiplying one coordinate by 1.001 or 1.01 (edit: now even 2 and 10!). Still, I miss some collisions.

Here is what I do in pseudo-code:

Code: Select all

btCollisionWorld world = create_trimesh_world()
radius=200

while(sth) {
    Point p = random_point()
    Point px( modify_plus(p.x), p.y, p.z )
    Point p_x( modify_minus(p.x), p.y, p.z )
    Point py( p.x, modify_plus(p.y), p.z )
    Point p_y( p.x, modify_minus(p.y), p.z )
    Point pz(p.x, p.y, modify_plus(p.z) )
    Point p_z(p.x, p.y, modify_minus(p.z) )

    if( !collision(p,px,radius) || !collision(p,p_x,radius) || !collision(p,py,radius) 
     || !collision(p,p_y,radius) || !collision(p,pz,radius) || !collision(p,p_z,radius) ) {
        enter_sphere(world, p, radius)
    }
}

bool collision(Point p1, Point p2) {
    btSphereShape sphere(radius)
    btCollisionWorld::ClosestConvexResultCallback callback(p1, p2)
    world.convexSweepTest( &sphere, p1, p2, callback, 0.1 )
    return callback.hasHit()
}
From the output I can see that some spheres actually intersect. As I have used this output in quite some other contexts, I have reason to believe that it is correct. If I replace the ORs with ANDs, it seems to work. But it seems that shouldn't be necessary, doesn't it?

One more thing: what I actually do is run the PRM algorithm. That means that in enter_sphere(), I search for the current sphere's n (atm 6) nearest neighbor spheres and try to connect them. This is done with the same collision() function that is used in above pseudo-code. The result is that colliding sphere always stay lonely, i.e. collision detection seems to work if the cast is long enough.

So I guess I could make it work if I make the factor big enough, but that's not what I actually want: It distorts the result compared to the ideal algorithm.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Collisions between Collision World and static convex object

Post by Erwin Coumans »

Using convexSweepTest to perform a discrete check (using a small offset) is a hack that is not recommended.

Either use a btGhostObject and perform a discrete check (this is what the btKinematicCharacterController uses to recover from penetrations) or perform the collision check manually.
I'll search/provide some example how to do this soon, please wait a little bit,
Thanks,
Erwin