Esempio n. 1
0
OSG_BASE_DLLMAPPING 
bool intersect(const BoxVolume &box, const SphereVolume &sphere)
{
    // source:
    // J. Arvo. A simple method for box-sphere intersection testing.
    // In A. Glassner, editor, Graphics Gems, pp. 335-339,
    // Academic Press, Boston, MA, 1990

    bool    retCode;
   
    if(box.isEmpty() == true || sphere.isEmpty() == true)
    {
        retCode = false;
    }
    else if(box.isInfinite() == true || sphere.isInfinite() == true)
    {
        retCode = true;
    }
    else
    {
        Real32  s;
        Real32  d = 0.f;

        //find the square of the distance from the sphere to the box

        for(Int32 i = 0; i < 3; i++)
        {
            if(sphere.getCenter()[i] < box.getMin()[i])
            {
                s  = sphere.getCenter()[i] - box.getMin()[i];
                d += s * s;
            }
            else if(sphere.getCenter()[i] > box.getMax()[i])
            {
                s  = sphere.getCenter()[i] - box.getMax()[i];
                d += s * s;
            }
        }

        retCode = (d <= (sphere.getRadius() * sphere.getRadius()));
    }

    return retCode;
}
bool Line::intersect(const SphereVolume &sphere,
                           Real         &enter, 
                           Real         &exit  ) const
{
    Vec3r v;
    Pnt3r center;

    sphere.getCenter(center);

    Real radius;
    Real h;
    Real b;
    Real d;
    Real t1;
    Real t2;

    radius = sphere.getRadius();

    v = center - _pos;

    h = (v.dot(v))-(radius * radius);
    b = (v.dot(_dir));

    if(h >= 0.f && b <= 0.f)
        return false;

    d = b * b - h;

    if(d < 0.f)
        return false;

    d  = osgSqrt(d);
    t1 = b - d;

//    if (t1 > 1)
//        return false;

    t2 = b + d;

    if( t1 < TypeTraits<Real>::getDefaultEps() )
    {
        if( t2 < TypeTraits<Real>::getDefaultEps() /*|| t2 > 1*/)
        {
            return false;
        }
    }

    enter = t1;
    exit  = t2;

    return true;
}
Esempio n. 3
0
OSG_BASE_DLLMAPPING 
bool intersect(const SphereVolume &sphere, const FrustumVolume &frustum)
{
    const Plane             *frust = frustum.getPlanes();

    //check the center of the sphere with each plane of the frustum
    for(Int32 i = 0; i < 6; i++)
    {
        if(frust[i].distance(sphere.getCenter()) < -sphere.getRadius())
            return false;
    }

    return true;
}
Esempio n. 4
0
OSG_BASE_DLLMAPPING 
bool intersect(const SphereVolume &sphere1, const SphereVolume &sphere2)
{
    bool    retCode = false;
    Real32  dist    = (sphere2.getCenter() - sphere1.getCenter()).length();

    if(sphere1.isEmpty() || sphere2.isEmpty())
    {
        retCode = false;
    }
    else if(sphere1.isInfinite() || sphere2.isInfinite())
    {
        retCode = true;
    }
    else if(dist < sphere1.getRadius() + sphere2.getRadius())
    {
        // the distance between the center of the 2 spheres is bigger
        // than the sum of the 2 radiuses

        retCode = true;
    }

    return retCode;
}
Esempio n. 5
0
OSG_BASE_DLLMAPPING 
bool intersect(const SphereVolume &sphere, const CylinderVolume &cylinder)
{
    bool  retCode;
    Pnt3f apos;
    Vec3f adir;

    cylinder.getAxis(apos, adir);

    if(sphere.isEmpty() || cylinder.isEmpty())
    {
        retCode = false;
    }
    else if(sphere.isInfinite() || cylinder.isInfinite())
    {
        retCode = true;
    }
    else
    {
        Real32  d = 0.f, s1 = 0.f, s2 = 0.f;
        Pnt3f   c;
        Vec3f   u, u1, u2;

        //get the distance between the upper and lower point of the cylinder
        // and the sphere center

        s1 = (apos        - sphere.getCenter()).length();
        s2 = (apos + adir - sphere.getCenter()).length();

        if ((s1<=DBL_EPSILON) || (s2<=DBL_EPSILON)) 
            return true;
        
        //check the smallest distance and set the vector coordinate
        if(s1 <= s2)
        {
            d = s1;
            c = apos;
        }
        else
        {
            d = s2;
            c = apos + adir;
        }

        // decompose the vector in u1 and u2 which are parallel and 
        // perpendicular to the cylinder axis respectively

        u  = ((d - sphere.getRadius()) / d) * (c - sphere.getCenter());

        u1 = (u[0] * adir[0] + u[1] * adir[1] + u[2] * adir[2]) / 
             (adir.length() * adir.length()) * adir;
        u2 = u - u1;

        if(u2.length() <= 10e-6)
        {
            retCode = (d <= sphere.getRadius());
        }
        else
        {
            retCode = (u2.length() <= cylinder.getRadius());
        }
    }

    return retCode;
}
Esempio n. 6
0
OSG_BASE_DLLMAPPING 
void extend(CylinderVolume &srcVol, const SphereVolume &vol)
{
    Pnt3f  min, max, min1, max1, min2, max2, apos;
    Vec2f  p;
    Vec3f  adir;
    Real32 r;

    if((!srcVol.isValid   () && !srcVol.isEmpty()) ||
         srcVol.isInfinite()                       ||
         srcVol.isStatic  ()                         )
    {
        return;
    }

    if(!vol.isValid())
        return;

    if(srcVol.isEmpty())
    {
        if(vol.isEmpty())
        {
            return;
        }
        else
        {
            r = vol.getRadius();

            apos = Pnt3f(vol.getCenter().x() - r, 
                         vol.getCenter().y() - r,
                         vol.getCenter().z() - r);
            adir = Vec3f(vol.getCenter().x() + r - apos.x(),
                         vol.getCenter().y() + r - apos.y(),
                         vol.getCenter().z() + r - apos.z());

            srcVol.setValue(apos, adir, r);

            return;
        }
    }
    else if(vol.isEmpty())
    {
        return;
    }

    srcVol.getBounds(min,  max);
    vol   .getBounds(min1, max1);

    min2 = Pnt3f(osgMin(min.x(), min1.x()), 
                 osgMin(min.y(), min1.y()),
                 osgMin(min.z(), min1.z()));
    max2 = Pnt3f(osgMax(max.x(), max1.x()), 
                 osgMax(max.y(), max1.y()),
                 osgMax(max.z(), max1.z()));

    p = Vec2f(max2.x() - min2.x(), max2.y() - min2.y());
    r = (p.length()) * 0.5f;

    adir = Vec3f(0.f, 0.f, max2.z() - min2.z());
    apos = Pnt3f(p.x(), p.y(), min2.z());

    srcVol.setValue(apos, adir, r);

    return;
}