Beispiel #1
0
OSG_BASE_DLLMAPPING 
bool intersect(const FrustumVolume &frustum, const Volume &vol, 
               FrustumVolume::PlaneSet &inplanes)
{
    Pnt3f min, max;
    vol.getBounds(min, max);
     
    const Plane             *frust = frustum.getPlanes();
    FrustumVolume::PlaneSet  mask  = 0x1;
   
    // check the box against the 6 planes, adjust the inplanes set
    // accordingly

    for(Int32 i = 0; i < 6; i++, mask <<= 1)
    {
        if((inplanes & mask) != 0)
            continue;
        
        if(frust[i].isOutHalfSpace(min, max))
            return false;
        
        if(frust[i].isInHalfSpace(min, max))
            inplanes |= mask;
    }

    return true;
}
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;
}
OSG_BASE_DLLMAPPING 
bool intersect(const CylinderVolume &cylinder, const FrustumVolume &frustum)
{
    Pnt3f min, max;
    cylinder.getBounds(min, max);

    const Plane       *frust = frustum.getPlanes();

    // check each point of the box to the 6 planes

    for(Int32 i = 0; i < 6; i++)
    {
        if(frust[i].isOutHalfSpace(min, max))
            return false;
    }

    return true;
}
Beispiel #4
0
OSG_BEGIN_NAMESPACE

OSG_BASE_DLLMAPPING bool
operator ==(const FrustumVolume &lhs, const FrustumVolume &rhs)
{
    return ((static_cast<const Volume &>(lhs) == rhs ) &&
            (lhs.getPlanes()[0] == rhs.getPlanes()[0]) &&
            (lhs.getPlanes()[1] == rhs.getPlanes()[1]) &&
            (lhs.getPlanes()[2] == rhs.getPlanes()[2]) &&
            (lhs.getPlanes()[3] == rhs.getPlanes()[3]) &&
            (lhs.getPlanes()[4] == rhs.getPlanes()[4]) &&
            (lhs.getPlanes()[5] == rhs.getPlanes()[5]));
}
/*! Calculate the vertices (\a intVerts) and center (\a intCenter) of
    the intersection of \a fA and \a fB.
 */
void TrapezoidalShadowMapEngine::intersectFrusta(
    const FrustumVolume      &fA,       const FrustumVolume &fB,
          std::vector<Pnt3r> &intVerts,       Pnt3r         &intCenter)
{
    const Plane *planes[12];

    intVerts.clear  (  );
    intVerts.reserve(16);
  
    for(UInt32 i = 0; i < 6; ++i)
    {
        planes[i    ] = &(fA.getPlanes()[i]);
        planes[6 + i] = &(fB.getPlanes()[i]);
    }

    // take all combinations of 3 planes -- but avoid choosing planes
    // we know to be parallel (i.e. near and far of the same frustum), or
    // that are known to intersect outside the frustum (i.e top/bottom,
    // left/right).

    for(UInt32 i = 0; i < 12; ++i)
    {
        // choose initial value of j such that it avoids near and far of fA
        for(UInt32 j = osgMax<UInt32>(2, i + 1); j < 12; ++j)
        {
            // near/far are parallel,
            // left/right always intersect outside the frustum,
            // top/bottom always intersect outside the frustum
            if((i == 6 && j == 7) ||
               (i == 2 && j == 3) || (i ==  8 && j ==  9) ||
               (i == 4 && j == 5) || (i == 10 && j == 11)   )
                continue;

            Line intLine;
            if(planes[i]->intersect(*planes[j], intLine) == false)
                continue;

            for(UInt32 k = j + 1; k < 12; ++k)
            {
                // near/far are parallel,
                // left/right always intersect outside the frustum,
                // top/bottom always intersect outside the frustum
                if((j == 6 && k == 7) ||
                   (j == 2 && k == 3) || (j ==  8 && k ==  9) ||
                   (j == 4 && k == 5) || (j == 10 && k == 11)   )
                    continue;

                Pnt3r intPoint;
                if(planes[k]->intersectInfinite(intLine, intPoint) == false)
                    continue;

                bool intPointValid = true;

                // check the intersection point against all planes to ensure
                // it is in both frusta
                for(UInt32 m = 0; m < 12; ++m)
                {
                    // intPoint is the intersection of planes i, j, k, so
                    // we don't have to test against those
                    if(m == i || m == j || m == k)
                        continue;

                    if(planes[m]->isInHalfSpace(intPoint) == false)
                    {
                        intPointValid = false;
                        break;
                    }
                }

                if(intPointValid == true)
                {
                    intCenter += intPoint.subZero();
                    intVerts.push_back(intPoint);
                }
            }
        }
    }

    intCenter /= intVerts.size();
}
bool Line::intersect(const FrustumVolume &frustum ,
                           Real          &enter   ,
                           Real          &exit    ) const
{
    const Real inf = 2u << 16;

    Pnt3r enter_point = _pos + _dir * 0.f;
    Pnt3r exit_point  = _pos + _dir * inf;

    face faces[6];

    const Plane *planes = frustum.getPlanes();

    Line lines[2];

    //ln[0] - intersection of right and top planes
    planes[3].intersect(planes[4], lines[0]); 

    //ln[1] - left and bottom
    planes[2].intersect(planes[5], lines[1]); 
    
    Pnt3r pointA;
    Pnt3r pointB;

    if(!planes[0].intersectInfinite(lines[0],pointA))
        std::cout << "This should never happen (A)!!!!";
                    
    if(!planes[1].intersectInfinite(lines[1],pointB))
        std::cout << "This should never happen (B)!!!!";

    faces[0].point        = pointA; 
    faces[0].inner_vector = pointB - pointA;

    faces[1].point        = pointB; 
    faces[1].inner_vector = pointA - pointB;

    faces[2].point        = pointB; 
    faces[2].inner_vector = pointA - pointB;

    faces[3].point        = pointA; 
    faces[3].inner_vector = pointB - pointA;

    faces[4].point        = pointA; 
    faces[4].inner_vector = pointB - pointA;

    faces[5].point        = pointB; 
    faces[5].inner_vector = pointA - pointB;

    for(Int32 i = 0; i < 6; i++)
    {
        faces[i].inner_normal=planes[i].getNormal();

        if(faces[i].inner_normal.dot(faces[i].inner_vector) < 0.f)
            faces[i].inner_normal=-faces[i].inner_normal;

        Vec3r test_enp = enter_point - faces[i].point;
        Vec3r test_exp = exit_point  - faces[i].point;

        Real value_enp = test_enp.dot(faces[i].inner_normal);
        Real value_exp = test_exp.dot(faces[i].inner_normal);

        if(value_enp < 0.f && value_exp < 0.f) 
            return false;

        if(value_enp > 0.f && value_exp < 0.f) 
            planes[i].intersect(*this, exit_point );

        if(value_enp < 0.f && value_exp > 0.f) 
            planes[i].intersect(*this, enter_point);
    }
    
    Real a;
    
    if((a = (enter_point - _pos).dot(_dir)) != 0.f)
    {
        enter = (enter_point - _pos).dot(enter_point - _pos) / a;
    }
    else 
    {
        enter = 0.f;
    }

    if((a = (exit_point  - _pos).dot(_dir)) != 0.f)
    {
        exit  = (exit_point  - _pos).dot(exit_point  - _pos) / a;
    }
    else
    {
        enter = 0.f;              
    }

    return true;
}