Esempio n. 1
0
OSG_BASE_DLLMAPPING 
bool intersect(const BoxVolume &box1, const BoxVolume &box2)
{
    bool retCode = false;

    if(box1.isEmpty() == true || box2.isEmpty() == true)
    {
        retCode = false;
    }
    else if(box1.isInfinite() == true || box2.isInfinite() == true)
    {
        retCode = true;
    }
    else
    {
        retCode =
            (box1.getMin()[0] <= box2.getMax()[0] &&
             box1.getMax()[0] >= box2.getMin()[0]   ) &&
            (box1.getMin()[1] <= box2.getMax()[1] &&
             box1.getMax()[1] >= box2.getMin()[1]   ) &&
            (box1.getMin()[2] <= box2.getMax()[2] &&
             box1.getMax()[2] >= box2.getMin()[2]   );
    }

    return retCode;
}
Esempio n. 2
0
OSG_BASE_DLLMAPPING 
void extend(BoxVolume &srcVol, const BoxVolume &vol)
{
    if( (!srcVol.isValid   () && !srcVol.isEmpty()) ||
          srcVol.isInfinite()                       ||
          srcVol.isStatic  ()                         )
    {
        return;
    }

    if(!vol.isValid())
        return;

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

    srcVol.setBounds(osgMin(vol.getMin().x(), srcVol.getMin().x()),
                     osgMin(vol.getMin().y(), srcVol.getMin().y()),
                     osgMin(vol.getMin().z(), srcVol.getMin().z()),
                     osgMax(vol.getMax().x(), srcVol.getMax().x()),
                     osgMax(vol.getMax().y(), srcVol.getMax().y()),
                     osgMax(vol.getMax().z(), srcVol.getMax().z()));

    if(vol.isInfinite())
        srcVol.setInfinite(true);

    return;
}
Esempio n. 3
0
OSG_BASE_DLLMAPPING 
void extend(BoxVolume &srcVol, const CylinderVolume &vol)
{
    Pnt3f min, max;

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

    if(!vol.isValid())
        return;

    if(srcVol.isEmpty())
    {
        if(vol.isEmpty())
        {
            return;
        }
        else
        {
            vol   .getBounds(min, max);
            srcVol.setBounds(min, max);

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

    vol.getBounds(min, max);

    srcVol.setBounds(osgMin(min.x(), srcVol.getMin().x()),
                     osgMin(min.y(), srcVol.getMin().y()),
                     osgMin(min.z(), srcVol.getMin().z()),
                     osgMax(max.x(), srcVol.getMax().x()),
                     osgMax(max.y(), srcVol.getMax().y()),
                     osgMax(max.z(), srcVol.getMax().z()));

    if(vol.isInfinite())
        srcVol.setInfinite(true);

    return;
}
Esempio n. 4
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;
}
// visibility levels
bool RenderPartition::pushVisibility(Node * const pNode)
{
    if(getFrustumCulling() == false)
        return true;

    FrustumVolume::PlaneSet inplanes = _visibilityStack.back();

    if(inplanes == FrustumVolume::P_ALL)
    {
        _visibilityStack.push_back(inplanes);

        return true;
    }

    Color3f col;
    bool result = true;

    FrustumVolume frustum = _oFrustum;
    BoxVolume     vol     = pNode->getVolume();

    // don't mess with infinite volumes
    if(vol.isInfinite() == false)
    {
        pNode->updateVolume();

        vol = pNode->getVolume();

#if 1
        vol.transform(topMatrix());
#else
    // not quite working
        Matrix m = topMatrix();
        m.invert();

        frustum.transform(m);
#endif
    }

    if(_oDrawEnv.getStatCollector() != NULL)
    {
        _oDrawEnv.getStatCollector()->getElem(statCullTestedNodes)->inc();
    }

    if(intersect(frustum, vol, inplanes) == false)
    {
         result = false;

         col.setValuesRGB(1,0,0);

         if(_oDrawEnv.getStatCollector() != NULL)
         {
             _oDrawEnv.getStatCollector()->getElem(statCulledNodes)->inc();
         }
    }
    else
    {
        if(inplanes == FrustumVolume::P_ALL)
        {
            col.setValuesRGB(0,1,0);
        }
        else
        {
            col.setValuesRGB(0,0,1);
        }
    }

    if(getVolumeDrawing())
    {
        dropVolume(this, pNode, col);
    }

    _visibilityStack.push_back(inplanes);

    return result;
}
Esempio n. 6
0
OSG_BASE_DLLMAPPING 
bool intersect(const BoxVolume &box, const CylinderVolume &cylinder)
{
    bool  retCode;
    Pnt3f apos;
    Vec3f adir;

    cylinder.getAxis(apos, adir);

    if(box.isEmpty() == true || cylinder.isEmpty() == true)
    {
        retCode = false;
    }
    else if(box.isInfinite() == true || cylinder.isInfinite() == true)
    {
        retCode = true;
    }
    else
    {
        Real32  s1 = 0, s2 = 0, s3 = 0, s4 = 0, d = 0, d1 = 0, d2 = 0;
        Pnt3f   c, p, p1, p2;
        Vec3f   u, u1, u2;

        // find the distance between the min and the max of the box
        //with the lower point and the upper point of the cylinder respectively

        s1 = (apos - box.getMin()).length();
        s2 = (apos - box.getMax()).length();

        s3 = (apos + adir - box.getMin()).length();
        s4 = (apos + adir - box.getMax()).length();

        //Check the minimum of the above distances

        if(s1 <= s2)
        {
            d1 = s1;
            p1 = box.getMin();
        }
        else
        {
            d1 = s2;
            p1 = box.getMax();
        }

        if(s3 <= s4)
        {
            d2 = s3;
            p2 = box.getMin();
        }
        else
        {
            d2 = s4;
            p2 = box.getMax();
        }

        //set the value of the vector corresponding to the shortest distance
        if(d1 <= d2)
        {
            d = d1;
            c = apos;
            p = p1;
        }
        else
        {
            d = d2;
            c = apos + adir;
            p = p2;
        }

        // decompose the vector in u1 and u2 which are parallel and 
        // perpendicular to the cylinder axis respectively
        u  = p - c;
        u1 = (u[0] * adir[0] + u[1] * adir[1] + u[2] * adir[2]) /
            (adir.length() * adir.length()) * adir;

        u2 = u - u1;

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

    return retCode;
}