Picking with Bullet

I'm using the Bullet physics library in my program and am currently trying to implement picking. The way the world is currently set up, there is a terrain with a box on top of it. Whenever I click on the box, my program only registers that the terrain has been clicked and doesn't recognize that the box has been clicked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void PhysicsEngine::RayTest()
{
    vec2 Mouse = MOUSE_POSITION;
    Mouse.y = WINDOW_DIMENSIONS.y - Mouse.y;

    vec4 RayStart = vec4(2*Mouse.x/WINDOW_DIMENSIONS.x - 1,2*Mouse.y/WINDOW_DIMENSIONS.y - 1, -1, 1);
    vec4 RayEnd = RayStart; RayEnd.z = 0;
    RayStart = inverse( StandardProgram.Get_Projection()*StandardProgram.Get_View() )*RayStart; RayStart /= RayStart.w;
    RayEnd = inverse( StandardProgram.Get_Projection()*StandardProgram.Get_View() )*RayEnd; RayEnd /= RayEnd.w;
    vec4 RayDirection = 1000*normalize(RayEnd-RayStart);

    btCollisionWorld::AllHitsRayResultCallback RayCallback(btVector3(RayStart.x,RayStart.y,RayStart.z),
                                                           btVector3(RayDirection.x,RayDirection.y,RayDirection.z));
    TheWorld->rayTest(btVector3(RayStart.x,RayStart.y,RayStart.z),
                      btVector3(RayDirection.x,RayDirection.y,RayDirection.z),
                      RayCallback);

    if ( RayCallback.hasHit() )
    {
        int Closest = 0;
        for ( int i = 0; i < RayCallback.m_collisionObjects.size(); i++ )
        {
            cout<<i<<": "<<ToVec3(RayCallback.m_hitPointWorld[i])<<" "
                <<RayCallback.m_hitFractions[i]<<" "
                <<RayCallback.m_collisionObjects[i]->getCollisionShape()->getShapeType()<<endl;

            if (RayCallback.m_hitPointWorld[i].getZ() >
                RayCallback.m_hitPointWorld[Closest].getZ() )
                Closest = i;
        }
    }
}


Does anyone notice anything wrong with the code?
¿wouldn't use a colour map be easier?

> my program only registers that the terrain has been clicked and doesn't recognize that the box has been clicked.
You mean that the terrain is the only object to collide (RayCallback.m_collisionObjects.size() == 1)
or that it is the "Closest"

¿why RayStart.z = -1?
¿why RayDirection.norm = 1000?
¿why in 'rayTest()' you are repeating the information contained in 'RayCallback'?
¿wouldn't use a colour map be easier?

Maybe but couldn't adding another render pass slow things down when rendering a large scene? I could be wrong but I'm worried with how colour mapping will scale

You mean that the terrain is the only object to collide (RayCallback.m_collisionObjects.size() == 1)
or that it is the "Closest"

I mean RayCallback.m_collisionObjects.size() == 1

¿why RayStart.z = -1?
¿why RayDirection.norm = 1000?
¿why in 'rayTest()' you are repeating the information contained in 'RayCallback'?


RayStart.z = -1 because at that moment it's in normalized device coordinates where z=-1 corresponds to the front of the scene

RayDirecion.norm = 1000 because the direction corresponds to how long the ray is as well as where if faces. So to make sure that all objects in that direction are registered, I used a long direction

As for the last question, that's just the way bullet does stuff. I don't know why it's like that
> Maybe but couldn't adding another render pass slow things down when rendering a large scene?
But the rendering for the colour map is simpler. No textures, no blending, no lighting, and you could reduce a lot the level of detail.



You may draw the testing ray in order to check that it is calculated properly.
Then, make sure that the 'rayTest()' function is actually passing through all the objects of interest.
Registered users can post here. Sign in or register to post.