Ray Test returning no hit

Post Reply
Alemarius Nexus
Posts: 5
Joined: Mon Jul 14, 2014 5:38 pm

Ray Test returning no hit

Post by Alemarius Nexus »

Hi,

I have a problem with raycasting in certain situations. I've narrowed down the problem to the following program:

Code: Select all

#include <cstdio>
#include <btBulletDynamicsCommon.h>


int main(int argc, char** argv)
{
    btDefaultCollisionConfiguration* config = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(config);
    btBroadphaseInterface* broadphase = new btDbvtBroadphase();
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
    btDiscreteDynamicsWorld* physicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, config);
    
    // A ground "plane"
    btBoxShape* shape = new btBoxShape(btVector3(1000.0f, 1000.0f, 0.25f));
    
    // Position the ground box so that its top surface is at Z = 200.0
    btDefaultMotionState* mstate = new btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f), btVector3(0.0f, 0.0f, 200.0f - 0.25f)));
    
    btRigidBody::btRigidBodyConstructionInfo info(0.0f, mstate, shape);
    btRigidBody* rb = new btRigidBody(info);
    
    physicsWorld->addRigidBody(rb);

#if 1
    // -> No Hit
    btVector3 rayStart(-2.003660f, 93.153000f, 218.825989f);
    btVector3 rayEnd(-2.009278f, 93.019928f, 180.947968f);
#else
    // -> Hit
    btVector3 rayStart(-2.003660f, 93.153000f, 218.825989f);
    btVector3 rayEnd(-2.009278f, 94.019928f, 180.947968f); // Slightly different Y coordinate
#endif

    btDynamicsWorld::ClosestRayResultCallback cb(rayStart, rayEnd);

    physicsWorld->rayTest(rayStart, rayEnd, cb);

    if (cb.hasHit()) {
        printf("Has hit!\n");
    } else {
        printf("Hasn't hit!\n");
    }
    
    return 0;
}
So I use a small box as a ground "plane" and cast a ray through this plane. The specific numbers here are some that I got from testing around. When using the points in the "#if 1" clause, the ray does not hit, but when using the "#else" clause, it does. The only difference is a minor change in the Y component of the ray end, but both rays should be hitting the ground plane.
Why does it not hit?

I've debugged a bit, and although I certainly don't understand the algorithms involved, it might be somewhere around btGjkConvexCast.cpp:163. An excerpt of a gdb session on this program:
(gdb) b btGjkConvexCast.cpp:163
Breakpoint 1 at 0x451fff: file /home/alemariusnexus/Development/source/bullet-2.82-r2704/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp, line 163.
(gdb) run
Starting program: /home/alemariusnexus/bullettest/./bullettest
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?

Breakpoint 1, btGjkConvexCast::calcTimeOfImpact (this=0x7fffffffd510, fromA=..., toA=..., fromB=..., toB=..., result=...) at /home/alemariusnexus/Development/source/bullet-2.82-r2704/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp:163
163 if (n.dot(r)>=-result.m_allowedPenetration)
(gdb) l
158
159 }
160
161 //is n normalized?
162 //don't report time of impact for motion away from the contact normal (or causes minor penetration)
163 if (n.dot(r)>=-result.m_allowedPenetration)
164 return false;
165
166 result.m_fraction = lambda;
167 result.m_normal = n;
(gdb) print n.dot(r)
$1 = 37,8763313
(gdb) print result.m_allowedPenetration
$2 = 0
(gdb) print n
$3 = {m_floats = {0,00606042799, 0,0044249231, -0,999971807, 0}}
(gdb) print r
$4 = {m_floats = {-0,0056180954, -0,133071899, -37,8780212, 0}}
I'm using bullet-2.82-r2704.

Does anybody know what's going on?


Thanks in advance!
Khanovich
Posts: 6
Joined: Thu May 15, 2014 6:28 am

Re: Ray Test returning no hit

Post by Khanovich »

If I remember correctly, for some reason default hitTest algorithms were consistently intermittently failing for me as well. If you search for m_flags inside of ClosestRayResultCallback you should be able to find a flag called "btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest".

Basically when I defined my RayCast callback I had to set this flag like this:

Code: Select all

btCollisionWorld::ClosestRayResultCallback resultCallback(from, to);
resultCallback.m_flags = btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest;
I never figured out why the default failed. Hope this helps.
Alemarius Nexus
Posts: 5
Joined: Mon Jul 14, 2014 5:38 pm

Re: Ray Test returning no hit

Post by Alemarius Nexus »

I tried this, and it did resolve some of the error cases. But I still get no hit with my test code (doesn't matter if the kF_UseSubSimplexConvexCastRaytest flag is set or not) for e.g. the following ray:

Code: Select all

btVector3 rayStart(-0.94f, -1.70f, 200.27f);
btVector3 rayEnd(-0.94f, -1.70f, 199.90f);
These two points are relatively near to the ground "plane" (as you see, it is actually a small box that is shifted so that the top face lies at 200.0f), so maybe there is some inaccuracy/tolerance going on somewhere? I don't know how this would affect a simple ray being cast to a box shape though. By the way, changing the Z component of the above rayStart vector to e.g. 201.0f makes the ray hit correctly. It also does hit correctly when I change the X component of both vectors to e.g. 0.0f, without changing the Z component. How can that make a difference? It all seems quite strange to me...
Post Reply