[ODE] Laser range finder

scott scott+ode at escherichia.net
Sun Sep 19 02:45:36 MST 2004


On Sat, Sep 18, 2004 at 03:03:00PM +0900, Ivan Tanev wrote:
> Hi,
> 
>I am trying to simulate a laser range finder in ODE & GLScene. The laser is
>shooting a "ray", which depending on (i) the position and orientation of the
>laser and (ii) the position, orientation and size of objects (obstacles, the
>ground plane, etc.) in the world may (or may not) "hit" some of these
>objects. Could you help me please: how to compute the "length" of such
>"ray".
> 
>Thank you,
> 
>Sincerely,
> 
>Ivan

Ivan,

You could use an ODE ray and collide it against the various geoms in your 
scene.  The contact generated by the ray's collision with another object
includes the point of collision.  The distance between that point and the
origin of your ray is the length of your laser.  The example code I am
including below fills a structure with the point of collision, distance to
the point of collision, and geom id of the object the ray collides with.
It will check up to a distance of 1000 units, and returns false if the
ray collides with nothing in the scene.

(Note the code below only checks for raycasts against spheres and boxes, 
but it should be easy enough for you to remove that filter.)

bool CollisionManager::raycast( RaycastResult &result, const dVector3 &p1, const dVector3 &dir )
{
    dGeomID ray = dCreateRay(m_collisionSpace,1000);
    dGeomRaySet( ray, p1[0], p1[1], p1[2], dir[0],dir[1],dir[2] );

    dContactGeom contact;

    int num = dSpaceGetNumGeoms(m_collisionSpace);

    bool hit = false;

    result.abscissa  = std::numeric_limits<float>::infinity();
    for (int ii=0; ii<num; ++ii)
    {
        dGeomID geo = dSpaceGetGeom(m_collisionSpace,ii);
        if ( dGeomGetClass( geo ) == dSphereClass || dGeomGetClass( geo ) == dBoxClass )
        {
            if ( dCollide( ray, geo, 1, &contact, sizeof(contact) ) )
            {
                //how far away is it.
                dVector3 diff;
                diff[0] = contact.pos[0] - p1[0];
                diff[1] = contact.pos[1] - p1[1];
                diff[2] = contact.pos[2] - p1[2];
                float distSqr = diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2];
                if ( distSqr < result.abscissa * result.abscissa )
                {
                    result.geom = geo;
                    result.x = contact.pos[0];
                    result.y = contact.pos[1];
                    result.z = contact.pos[2];
                    result.abscissa = sqrt( distSqr );
                }

                hit = true;
            }
        }
    }

    dSpaceRemove( m_collisionSpace, ray );
    dGeomDestroy( ray );
    return hit;
} // CollisionManager::raycast

scott

-- 
-----------------------------------------------------------------
scott jacobs                            scott+ode at escherichia.net
-----------------------------------------------------------------


More information about the ODE mailing list