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()
}
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.