Ejemplo n.º 1
0
OSG_BASE_DLLMAPPING 
void extend(BoxVolume &srcVol, const Volume &vol)
{
    const Volume        *v       = &vol;
    const BoxVolume     *box;
    
#ifndef OSG_2_PREP
    const DynamicVolume *dynamic = dynamic_cast<const DynamicVolume *>(v);

    if(dynamic)
    {
        v = &(dynamic->getInstance());
    }
#endif

    if((box = dynamic_cast<const BoxVolume *>(v)))
    {
        OSG::extend(srcVol, *box);
    }
    else
    {
        BoxVolume   localBox;
        Pnt3f       min, max;

        v->getBounds(min, max);

        localBox.setBounds(min, max);

        OSG::extend(srcVol, localBox);
    }
}
Ejemplo n.º 2
0
UInt32 ParticleBSPTree::doBuild(std::vector<Int32>::iterator  begin, 
                                std::vector<Int32>::iterator  end,
                                     UInt32                   nodeindex,
                                     GeoVectorProperty       *pos)
{
    // reached a leaf?
    
    if(begin + 1 == end)
    {
        _tree[nodeindex].setValue(*begin);
        return nodeindex + 1;
    }
    
    // find the bounding volume of the group
    
    BoxVolume b;
    Pnt3f p;
    
    b.setEmpty();
    
    for(std::vector<Int32>::iterator i = begin; i != end; ++i)
    {
        pos->getValue(p,*i);     
        b.extendBy(p);
    }
    
    // find the axis with the longest extension
    
    Vec3f d = b.getMax() - b.getMin();
    
    UInt8 axis = ParticleBSPNode::X;
    Real32 maxval = d[0];
    
    if(d[1] > maxval)
    {
        axis = ParticleBSPNode::Y;
        maxval = d[1];
    }
    if(d[2] > maxval)
    {
        axis = ParticleBSPNode::Z;
        maxval = d[2];
    }

    // sort in that axis
    ParticleCompare comp(pos, axis);
    
    std::sort(begin,end,comp);
    
    // find median value
    std::vector<Int32>::iterator mid = begin + (end - begin) / 2;
    
    Pnt3f p2;
    pos->getValue(p ,*mid);
    pos->getValue(p2,(*mid)-1);
    _tree[nodeindex].setSplit(axis, (p[axis] + p2[axis]) / 2.f);
    
    return osgMax( doBuild(begin, mid, nodeindex * 2    , pos),
                   doBuild(  mid, end, nodeindex * 2 + 1, pos) );   
}   
OSG_BEGIN_NAMESPACE

#if 0
/*! Return a sphere containing a given box */
void SphereVolume::circumscribe(const BoxVolume &box)
{
    float radius = 0.5 * (box.getMax() - box.getMin()).length();
    Vec3f center;

    box.getCenter(center);

    setValue(center, radius);
}
Ejemplo n.º 4
0
/*! \ingroup GrpSystemDrawablesGeometryFunctions
    Draw the given BoxVolume using direct OpenGL calls.
*/
OSG_SYSTEMLIB_DLLMAPPING 
void OSG::drawVolume(const BoxVolume &volume)
{
    Pnt3f min,max;
    volume.getBounds(min, max);

    glBegin(GL_LINE_LOOP);
    glVertex3f(min[0], min[1], min[2]);   
    glVertex3f(max[0], min[1], min[2]);   
    glVertex3f(max[0], max[1], min[2]);   
    glVertex3f(min[0], max[1], min[2]);   
    glVertex3f(min[0], min[1], min[2]);   
    glVertex3f(min[0], min[1], max[2]);   
    glVertex3f(max[0], min[1], max[2]);   
    glVertex3f(max[0], max[1], max[2]);   
    glVertex3f(min[0], max[1], max[2]);   
    glVertex3f(min[0], min[1], max[2]);   
    glEnd();

    glBegin(GL_LINES);
    glVertex3f(min[0], max[1], min[2]);   
    glVertex3f(min[0], max[1], max[2]);   
    glVertex3f(max[0], max[1], min[2]);   
    glVertex3f(max[0], max[1], max[2]);   
    glVertex3f(max[0], min[1], min[2]);   
    glVertex3f(max[0], min[1], max[2]);   
    glEnd();

    return;
}
    Action::ResultE draw(DrawEnv *)
    {
        BoxVolume vol;
        _node->getWorldVolume(vol);
        Pnt3f Min,Max;
        vol.getBounds(Min,Max);

        Real32 Length(1.05f * (Max-Min).maxValue());
        drawPhysicsBodyCoordinateSystem(_body, Length);
        drawPhysicsBodyLinearVelocity(_body, Length);
        drawPhysicsBodyAngularVelocity(_body, Length);
        
        // self-destruct
        delete this;
        
        return Action::Continue;
    }
Ejemplo n.º 6
0
void Node::updateVolume(void)
{
    // still valid or static, nothing to do
    if(_sfVolume.getValue().isValid () == true   ||
       _sfVolume.getValue().isStatic() == true   ||
       getTravMask()                   == 0x0000   )
    {
        return;
    }

    // be careful to not change the real volume. If two threads
    // are updating the same aspect this will lead to chaos

    BoxVolume vol = _sfVolume.getValue();

    MFUnrecChildNodePtr::const_iterator cIt  = 
        this->getMFChildren()->begin();
    MFUnrecChildNodePtr::const_iterator cEnd = 
        this->getMFChildren()->end();

    vol.setEmpty();

    for(; cIt != cEnd; ++cIt)
    {
        if(*cIt != NULL && (*cIt)->getTravMask())
        {
            (*cIt)->updateVolume();
            vol.extendBy((*cIt)->getVolume());
        }
    }

    // test for null core. Shouldn't happen, but just in case...
    if(getCore() != NULL)
    {
        getCore()->adjustVolume(vol);
    }

    // don't propagate the static flag from children
    vol.setStatic(false);

    editSField(VolumeFieldMask);

    _sfVolume.setValue(vol);
}
// test a single node
bool RenderPartition::isVisible(Node *pNode)
{
    if(getFrustumCulling() == false)
        return true;

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

//    _oDrawEnv.getRTAction()->getStatistics()->getElem(statCullTestedNodes)->inc();

    if(pNode->getVolume().isInfinite() == true)
        return true;

    BoxVolume vol;

    pNode->updateVolume();

    vol = pNode->getVolume();

    vol.transform(topMatrix());

    if(_oFrustum.intersect(vol))
    {
// fprintf(stderr,"%p: node 0x%p vis\n", Thread::getCurrent(), node);
        return true;
    }

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

//    _oDrawEnv.getRTAction()->getStatistics()->getElem(statCulledNodes)->inc();

// fprintf(stderr,"%p: node 0x%p invis\n", Thread::getCurrent(), node);
// _frustum.dump();

    return false;
}
Ejemplo n.º 8
0
OSG_BASE_DLLMAPPING 
bool intersect(const BoxVolume &box, const FrustumVolume &frustum)
{
    Pnt3f min, max;
    box.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;
}
Ejemplo n.º 9
0
void Node::getWorldVolume(BoxVolume &result)
{
    Matrix m;

    if(getParent() != NULL)
    {
        getParent()->getToWorld(m);
    }
    else
    {
        m.setIdentity();
    }

    updateVolume();

    result = getVolume();
    result.transform(m);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
bool Line::intersect(const BoxVolume &box,
                           Real      &enter, 
                           Real      &exit ) const
{
    Pnt3r low;
    Pnt3r high;

    box.getBounds(low, high);

    Real r;
    Real te;
    Real tl;

    Real in  = 0.f;
    Real out = Inf;

    if(_dir[0] > TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[0];
    
        te = (low [0] - _pos[0]) * r;
        tl = (high[0] - _pos[0]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    }
    else if(_dir[0] < -TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[0];
    
        te = (high[0] - _pos[0]) * r;
        tl = (low [0] - _pos[0]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    }
    else if(_pos[0] < low[0] || _pos[0] > high[0])
    {
        return false;
    }
    
    if(_dir[1] > TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[1];
    
        te = (low [1] - _pos[1]) * r;
        tl = (high[1] - _pos[1]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    
        if(in-out >= TypeTraits<Real>::getDefaultEps())
            return false;
    }
    else if(_dir[1] < -TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[1];
    
        te = (high[1] - _pos[1]) * r;
        tl = (low [1] - _pos[1]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    
        if(in-out >= TypeTraits<Real>::getDefaultEps())
            return false;
    }
    else if(_pos[1] < low[1] || _pos[1] > high[1])
    {
        return false;
    }
    
    if(_dir[2] > TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[2];
    
        te = (low [2] - _pos[2]) * r;
        tl = (high[2] - _pos[2]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    }
    else if(_dir[2] < -TypeTraits<Real>::getDefaultEps())
    {
        r = 1.f / _dir[2];
    
        te = (high[2] - _pos[2]) * r;
        tl = (low [2] - _pos[2]) * r;
    
        if(tl < out)   
            out = tl;
    
        if(te > in)    
            in  = te;
    }
    else if(_pos[2] < low[2] || _pos[2] > high[2])
    {
        return false;
    }

    enter = in;
    exit  = out;

    // Eps: count flat boxes as intersected


    // BUGFIXED, was:  

    // return enter-exit < Eps;

    // This got unstable with bbox check of huge planes
    // and if compiled as opt lib (at least with my gcc 4.0.2).
    // However it worked when compiled as dbg lib. 

    // And now something completely different...

    return in-out < TypeTraits<Real>::getDefaultEps();

    // To get you even more confused: It also works if you leave it
    // as "enter-exit" but declare in/out as Real64.

    // Now think about it......and if it is not 42, please tell!
}
void SortLastWindow::collectDrawables(Node * const   node,
                                      DrawableListT &drawables)
{
    Material *mat  = NULL;
    NodeCore *core = node->getCore();

    if(core != NULL)
    {
        // handle material groups
        MaterialGroup *matGrp = dynamic_cast<MaterialGroup *>(core);

        if(matGrp != NULL)
        {
            mat = matGrp->getMaterial();

            // ignore transparent material groups
            if(mat != NULL && mat->isTransparent())
                return;
        }

        // handle geometries
        Geometry *geo = dynamic_cast<Geometry *>(core);

        if(geo != NULL)
        {
            mat = geo->getMaterial();
            // ignore transparent materials

            if(mat == NULL || mat->isTransparent() == false)
            {
                DrawableInfo drawableInfo;

                drawableInfo.node = node;

                // get transformed volume
                node->updateVolume();

                BoxVolume volume;
                node->getWorldVolume(volume);

                // get min,max
                volume.getBounds(drawableInfo.bMin, drawableInfo.bMax);

                // num of indices
                drawableInfo.load = 0;

                GeoIntegralProperty *indicesPtr = 
                    geo->getIndex(Geometry::PositionsIndex);

                if(indicesPtr != NULL)
                    drawableInfo.load = indicesPtr->size();

                // put to list
                drawables.push_back(drawableInfo);
            }
        }

        // handle poxy groups
        ProxyGroup *proxy = dynamic_cast<ProxyGroup *>(core);

        if(proxy != NULL)
        {
            DrawableInfo drawableInfo;

            drawableInfo.node = node;

            // get transformed volume
            node->updateVolume();

            BoxVolume volume;
            node->getWorldVolume(volume);

            // get min,max
            volume.getBounds(drawableInfo.bMin, drawableInfo.bMax);

            // num of indices
            drawableInfo.load = proxy->getIndices();

            // put to list
            drawables.push_back(drawableInfo);
        }
    }
    
    MFUnrecChildNodePtr::const_iterator nI;

    for(  nI  = node->getMFChildren()->begin();
          nI != node->getMFChildren()->end();
        ++nI)
    {
        collectDrawables(*nI, drawables);
    }
}
Ejemplo n.º 13
0
    void selectedNodeChanged(void)
    {
        _mgr->setHighlight(_SelectedNode);


        //Update Details Panel
        if(_SelectedNode == NULL)
        {
            _NodeNameValueLabel->setText("");

            _NodeCoreTypeValueLabel->setText("");

            _NodeMinValueLabel->setText("");

            _NodeMaxValueLabel->setText("");

            _NodeCenterValueLabel->setText("");

            _NodeTriCountValueLabel->setText("");

            _NodeTravMaskValueLabel->setText("");
        }
        else
        {
            const Char8 *NodeName = getName(_SelectedNode);
            if(NodeName == NULL)
            {
                _NodeNameValueLabel->setText("Unnamed Node");
            }
            else
            {
                _NodeNameValueLabel->setText(NodeName);
            }

            _NodeCoreTypeValueLabel->setText(_SelectedNode->getCore()->getType().getCName());

            BoxVolume DyVol;
            _SelectedNode->getWorldVolume(DyVol);
            Pnt3f Min,Max,Center;
            DyVol.getBounds(Min,Max);
            DyVol.getCenter(Center);

            std::string TempText("");

            TempText = boost::lexical_cast<std::string>(Min.x())
                + ", " +boost::lexical_cast<std::string>(Min.x())
                + ", " + boost::lexical_cast<std::string>(Min.x());
            _NodeMinValueLabel->setText(TempText);

            TempText = boost::lexical_cast<std::string>(Max.x())
                + ", " +boost::lexical_cast<std::string>(Max.x())
                + ", " + boost::lexical_cast<std::string>(Max.x());
            _NodeMaxValueLabel->setText(TempText);

            TempText = boost::lexical_cast<std::string>(Center.x())
                + ", " +boost::lexical_cast<std::string>(Center.x())
                + ", " + boost::lexical_cast<std::string>(Center.x());
            _NodeCenterValueLabel->setText(TempText);

            _NodeTravMaskValueLabel->setText(boost::lexical_cast<std::string>(_SelectedNode->getTravMask()));

            //Tri Cound
            TriCountGraphOpRefPtr TheTriGraphOp = TriCountGraphOp::create();
            TheTriGraphOp->traverse(_SelectedNode);

            _NodeTriCountValueLabel->setText(boost::lexical_cast<std::string>(TheTriGraphOp->getNumTri()));
        }
    }
Ejemplo n.º 14
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;
}
// 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;
}
void SortLastWindow::splitDrawables(DrawableListT &src,
                                    UInt32         groups,
                                    bool           cut)
{
    BoxVolume                vol;
//    Real32                   srcLoad=0;
    Real32                   dst1Load = 0;
    Real32                   dst2Load = 0;
    DrawableListT::iterator  dI;
    UInt32                   dIFront  = 0;
    UInt32                   dIBack   = 0;
    UInt32                   axis     = 0;
    Vec3f                    size;
    DrawableListT            dst1;
    DrawableListT            dst2;
    UInt32                   groups1  = 0;
    UInt32                   groups2  = 0;

    // no group
    if(groups == 0)
        return;

    // only one group
    if(groups == 1)
    {
        editMFGroupLengths()->push_back(UInt32(src.size()));

        for(dI = src.begin() ; dI != src.end() ; ++dI)
        {
            pushToGroupNodes(dI->node);
//            srcLoad+=dI->load;
        }
//        printf("load:%f\n",srcLoad);
        return;
    }

    groups1 = groups / 2;
    groups2 = groups - groups1;

    // collect all load and get summed volume
    for(dI = src.begin() ; dI != src.end() ; ++dI)
    {
        vol.extendBy(dI->bMin);
        vol.extendBy(dI->bMax);
    }

    // get longes axis
    vol.getSize(size);

    if(size[0] > size[1])
    {
        if(size[0] > size[2])
            axis=0;
        else
            axis=2;
    }
    else
    {
        if(size[1] > size[2])
            axis=1;
        else
            axis=2;
    }

    // sort by volume
    if(axis == 0)
    {
        std::sort(src.begin(),src.end(), DrawableInfo::MaxXOrder());
    }
    else
    {
        if(axis == 1)
            std::sort(src.begin(),src.end(), DrawableInfo::MaxYOrder());
        else
            std::sort(src.begin(),src.end(), DrawableInfo::MaxZOrder());
    }

    // split group
    if(src.size())
    {
        dIFront  = 0;
        dIBack   = UInt32(src.size()) - 1;
        do
        {
//            printf("f %d  b %d\n",dIFront,dIBack);
            if(dst2Load < dst1Load)
            {
                dst2.push_back(src[dIBack]);

                dst2Load += src[dIBack].load*groups/Real32(groups2);

                dIBack--;
            }
            else
            {
                dst1.push_back(src[dIFront]);

                dst1Load += src[dIFront].load*groups/Real32(groups1);

                dIFront++;
            }
        } while(dIFront <= dIBack);
    }        
    // recourse
    splitDrawables(dst1, groups1, cut);
    splitDrawables(dst2, groups2, cut);
}
Ejemplo n.º 17
0
OSG_BASE_DLLMAPPING 
void extend(SphereVolume &srcVol, const BoxVolume &vol)
{
    Pnt3f     min, max, min1, max1, c;
    Real32    r;
    BoxVolume vol1;

    vol.getBounds(min, max);

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

    if(!vol.isValid())
        return;

    if(srcVol.isEmpty())
    {
        if(vol.isEmpty())
        {
            return;
        }
        else
        {
            c = Pnt3f((min.x() + max.x()) * 0.5f, 
                      (min.y() + max.y()) * 0.5f,
                      (min.z() + max.z()) * 0.5f);

            r = ((max - min).length()) / 2;

            srcVol.setValue(c, r);

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

    srcVol.getBounds(min1, max1);

    vol1.setBounds(osgMin(min.x(), min1.x()), osgMin(min.y(), min1.y()),
                   osgMin(min.z(), min1.z()), osgMax(max.x(), max1.x()),
                   osgMax(max.y(), max1.y()), osgMax(max.z(), max1.z()));

    vol1.getBounds(min, max);

    c = Pnt3f((min.x() + max.x()) * 0.5f, 
              (min.y() + max.y()) * 0.5f,
              (min.z() + max.z()) * 0.5f);

    r = ((max - min).length()) / 2;

    srcVol.setValue(c, r);

    return;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
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;
}
ActionBase::ResultE CubeMapGenerator::renderEnter(Action *action)
{
    static Matrix transforms[] = 
    { 
        Matrix( 1,  0,  0,  0,
                0, -1,  0,  0,
                0,  0, -1,  0,
                0,  0,  0,  1),
        
        Matrix(-1,  0,  0,  0,
                0, -1,  0,  0,
                0,  0,  1,  0,
                0,  0,  0,  1),
        
        Matrix( 1,  0,  0,  0,
                0,  0, -1,  0,
                0,  1,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 1,  0,  0,  0,
                0,  0,  1,  0,
                0, -1,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 0,  0, -1,  0,
                0, -1,  0,  0,
               -1,  0,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 0,  0,  1,  0,
                0, -1,  0,  0,
                1,  0,  0,  0,
                0,  0,  0,  1)
    };

    RenderAction *a = dynamic_cast<RenderAction *>(action);

    Action::ResultE  returnValue = Action::Continue;

    Background      *pBack    = a->getBackground();

    Viewport        *pPort    = a->getViewport();

    Node            *pActNode = a->getActNode();

    CubeMapGeneratorStageData *pData = 
        a->getData<CubeMapGeneratorStageData *>(_iDataSlotId);

    if(pData == NULL)
    {
        pData = this->initData(a);
    }

    TraversalValidator::ValidationStatus eStatus = this->validateOnEnter(a);

    if(eStatus == TraversalValidator::Run)
    {
        this->beginPartitionGroup(a);
        {
            FrameBufferObject *pTarget  = this->getRenderTarget();
                
            if(pTarget == NULL)
            {
                pTarget  = pData->getRenderTarget();
            }

            Pnt3f oOrigin;

            if(this->getOriginMode() == CubeMapGenerator::UseStoredValue)
            {
                oOrigin = this->getOrigin();
            }
            else if(this->getOriginMode() == CubeMapGenerator::UseBeacon)
            {
                fprintf(stderr, "CubemapGen::UseBeacon NYI\n");
            }
            else if(this->getOriginMode() == 
                                       CubeMapGenerator::UseCurrentVolumeCenter)
            {
                BoxVolume oWorldVol;

                commitChanges();

                pActNode->updateVolume();
                
                pActNode->getWorldVolume(oWorldVol);
                
                oWorldVol.getCenter(oOrigin);
            }
            else if(this->getOriginMode() == 
                                       CubeMapGenerator::UseParentsVolumeCenter)
            {
                fprintf(stderr, "CubemapGen::UseParentsCenter NYI\n");
            }

            Camera *pCam = pData->getCamera();

            pActNode->setTravMask(0);

            for(UInt32 i = 0; i < 6; ++i)
            {
                this->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();
                
                    pPart->setVolumeDrawing(false);

                    pPart->setRenderTarget(pTarget       );
                    pPart->setWindow      (a->getWindow());

                    pPart->calcViewportDimension(0,
                                                 0,
                                                 1,
                                                 1,
                                                 this->getWidth (),
                                                 this->getHeight());
                
                    Matrix m, t;
            
                    // set the projection
                    pCam->getProjection          (m, 
                                                  pPart->getViewportWidth (), 
                                                  pPart->getViewportHeight());
                
                    pCam->getProjectionTranslation(t, 
                                                   pPart->getViewportWidth (), 
                                                   pPart->getViewportHeight());
                
                    pPart->setupProjection(m, t);
            
                    m = transforms[i];
            
                    m[3][0] = oOrigin[0];
                    m[3][1] = oOrigin[1];
                    m[3][2] = oOrigin[2];

                    m.invert();

                    pPart->setupViewing(m);
            
                    pPart->setNear     (pCam->getNear());
                    pPart->setFar      (pCam->getFar ());
                    
                    pPart->calcFrustum();
                
                    if(this->getBackground() == NULL)
                    {
                        pPart->setBackground(pBack);
                    }
                    else
                    {
                        pPart->setBackground(this->getBackground());
                    }
                
                    if(this->getRoot() != NULL)
                    {
                        this->recurse(a, this->getRoot());
                    }
                    else
                    {
                        this->recurse(a, pPort->getRoot());
                    }

                    pPart->setDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);

#ifdef OSG_DEBUGX
                    std::string szMessage("CubeX\n");
                    pPart->setDebugString(szMessage          );
#endif
                }
                this->popPartition(a);
            }

            pActNode->setTravMask(~0);
        }
        this->endPartitionGroup(a);
    }

    OSG_ASSERT(pActNode == a->getActNode());

    returnValue = Inherited::renderEnter(action);

    action->useNodeList(false);

    return returnValue;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
int main (int argc, char **argv) {

    Real32 ent, ex;
    int i;

    //Lines:

    const int nlines = 10;

    Line lines[nlines];
    Pnt3f pnts[nlines * 2] = {
                        Pnt3f(0,0,0), Pnt3f(0,1,0),
                        Pnt3f(0,0,0), Pnt3f(2,1,0),
                        Pnt3f(2,0,0), Pnt3f(2,1,0),
                        Pnt3f(-2,0,0), Pnt3f(0,2,0),
                        Pnt3f(-4,2,0), Pnt3f(0,2,0),
                        Pnt3f(-3,0,0), Pnt3f(-2,1,0),
                        Pnt3f(3,4,0), Pnt3f(1,3,0),
                        Pnt3f(-1,0,0), Pnt3f(-1,1,0),
                        Pnt3f(-4,0,0), Pnt3f(-3,1,0),
                        Pnt3f(-4,6,0), Pnt3f(0,6,0)
                        };

    for ( i = 0; i < nlines; i++ )
        lines[i].setValue( pnts[i*2], pnts[i*2+1] );


    BoxVolume b;

    float xmin, ymin, zmin, xmax, ymax, zmax;

    xmin = 0;
    ymin = 0.5;
    zmin = 0;
    xmax = 1;
    ymax = .5;
    zmax = 1;

    b.setBounds(xmin, ymin, zmin, xmax, ymax, zmax);

    std::cout << std::endl;
    b.dump();
    std::cout << std::endl;

    for ( i = 0 ; i < nlines; i++ )
    {
        std::cout << "Line: (" << lines[i].getPosition() << ") ("
             << lines[i].getDirection() << ")" << std::endl;

        bool res = lines[i].intersect( b, ent, ex );
        Pnt3f   ep = lines[i].getPosition() + ent * lines[i].getDirection(),
                xp = lines[i].getPosition() + ex * lines[i].getDirection();

        std::cout << "Result: " << res;

        if ( res )
        {
            std::cout << " enter " << ent << "=(" << ep << ") ";

            bool es = ( b.isOnSurface( ep ) || b.intersect( ep ) ),
                 xs = b.isOnSurface( xp );

            if ( ( res && es ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";

            std::cout << ";  exit " << ex << "=(" << xp << ") ";

            if ( ( res && xs ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";
        }

        std::cout << std::endl;
    }

    return 0;

    SphereVolume s;

    float radius;
    Vec3f center;

    center[0] = 0;
    center[1] = 0;
    center[2] = 0;

    radius = 1;

    s.setCenter(center);
    s.setRadius(radius);

    std::cout << std::endl;
    s.dump();
    std::cout << std::endl;


    for ( i = 0 ; i < nlines; i++ )
    {
        std::cout << "Line: (" << lines[i].getPosition() << ") ("
                  << lines[i].getDirection() << ")" << std::endl;

        bool res = lines[i].intersect( s, ent, ex );
        Pnt3f   ep = lines[i].getPosition() + ent * lines[i].getDirection(),
                xp = lines[i].getPosition() + ex * lines[i].getDirection();

        std::cout << "Result: " << res;

        if ( res )
        {
            std::cout << " enter " << ent << "=(" << ep << ") ";

            bool es = ( s.isOnSurface( ep ) || s.intersect( ep ) ),
                 xs = s.isOnSurface( xp );

            if ( ( res && es ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";

            std::cout << ";  exit " << ex << "=(" << xp << ") ";

            if ( ( res && xs ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";
        }

        std::cout << std::endl;
    }

//  Intersect the line with a cylinder.


    Pnt3f p;
    Vec3f d;
    float rad;

    p[0] = 0;
    p[1] = 1;
    p[2] = 0;

    d[0] = 0;
    d[1] = 4;
    d[2] = 0;

    rad = 2;

    CylinderVolume c;

    c.setValue(p, d, rad);

//  c.setAxis(p, d);
//  c.setRadius(rad);

    std::cout << std::endl;
    c.dump();
    std::cout << std::endl;


    for ( i = 0 ; i < nlines; i++ )
    {
        std::cout << "Line: (" << lines[i].getPosition() << ") ("
             << lines[i].getDirection() << ")" << std::endl;

        bool res = lines[i].intersect( c, ent, ex );
        Pnt3f   ep = lines[i].getPosition() + ent * lines[i].getDirection(),
                xp = lines[i].getPosition() + ex * lines[i].getDirection();

        std::cout << "Result: " << res;

        if ( res )
        {
            std::cout << " enter " << ent << "=(" << ep << ") ";

            bool es = ( c.isOnSurface( ep ) || c.intersect( ep ) ),
                 xs = c.isOnSurface( xp );

            if ( ( res && es ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";

            std::cout << ";  exit " << ex << "=(" << xp << ") ";

            if ( ( res && xs ) || !res )    std::cout << "ok";
            else                            std::cout << "**BAD**";
        }

        std::cout << std::endl;
    }

    //### volume intersection ##############################################


    std::cout << "### volume intersection test ###" << std::endl;

    BoxVolume box(-1,-1,-1,1,1,1);
    BoxVolume boxOut (5,5,5,10,10,10);
    BoxVolume boxIn(-1,-1,-1,2,2,2);

    SphereVolume sphere(Pnt3f(0,0,0),2);
    SphereVolume sphereOut(Pnt3f(2,2,2),1);
    SphereVolume sphereIn(Pnt3f(1,0,0),1);

    CylinderVolume cylinder(Pnt3f(0,0,0),Vec3f(1,1,1),1);
    CylinderVolume cylinderOut(Pnt3f(0,9,9),Vec3f(0,0,1),1);
    CylinderVolume cylinderIn(Pnt3f(1,0,0),Vec3f(0,1,0),1);


    // Frustum defined by normal vector and distance

    Plane pnear(Vec3f(0,0,-1),2);
    Plane pfar(Vec3f(0,0,1),7);
    Plane pright(Vec3f(-0.7071,0,-0.7071),0);
    Plane pleft(Vec3f(0.7071,0,-0.7071),0);
    Plane ptop(Vec3f(0,-0.7071,-0.7071),0);
    Plane pbottom(Vec3f(0,0.7071,-0.7071),0);

    FrustumVolume frustum(pnear, pfar, pleft, pright, ptop, pbottom);

    //Frustum defined by a clipMatrix

    Matrix matrix;
    matrix.setValue(0.7071,0,0,0,
            0,0.7071,0,0,
            0,0,-1.27,-3.959,
            0,0,-0.7071,0);

    FrustumVolume frustum1;
    frustum1.setPlanes(matrix);

    // Frustum defined by 8 points

    Pnt3f nlt(-2,2,-2);
    Pnt3f nlb(-2,-2,-2);
    Pnt3f nrt(2,2,-2);
    Pnt3f nrb(2,-2,-2);
    Pnt3f flt(-7,7,-7);
    Pnt3f flb(-7,-7,-7);
    Pnt3f frt(7,7,-7);
    Pnt3f frb(7,-7,-7);

    FrustumVolume frustum2;
    frustum2.setPlanes(nlt, nlb, nrt, nrb, flt, flb, frt, frb);


        //Tests

    std::cout << "Box/box outside test: " << std::flush;
    std::cout << (box.intersect(boxOut) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Box/box inside test: " << std::flush;
    std::cout << (box.intersect(boxIn) ? "ok" : "**BAD**") << std::endl;

    std::cout << "Box/sphere outside test: " << std::flush;
    std::cout << (box.intersect(sphereOut) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Box/sphere inside test: " << std::flush;
    std::cout << (box.intersect(sphereIn) ? "ok" : "**BAD**")<< std::endl;

    std::cout << "Sphere/sphere outside test: " << std::flush;
    std::cout << (sphere.intersect(sphereOut) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Sphere/sphere inside test: " << std::flush;
    std::cout << (sphere.intersect(sphereIn) ? "ok" : "**BAD**") << std::endl;

    std::cout << "Box/cylinder outside test: " << std::flush;
    std::cout << (box.intersect(cylinderOut) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Box/cylinder inside test: " << std::flush;
    std::cout << (box.intersect(cylinderIn) ? "ok" : "**BAD**") << std::endl;

    std::cout << "Sphere/cylinder outside test: " << std::flush;
    std::cout << (sphere.intersect(cylinderOut) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Sphere/cylinder inside test: " << std::flush;
    std::cout << (sphere.intersect(cylinderIn) ? "ok" : " **BAD**") << std::endl;

    std::cout << "Cylinder/cylinder outside test: "<<std::flush;
    std::cout << (cylinder.intersect(cylinderOut) ? "**BAD**" : "ok")<<std::endl;

    std::cout << "Cylinder/cylinder inside test: "<<std::flush;
    std::cout << (cylinder.intersect(cylinderIn) ? "ok" : " **BAD** ")<<std::endl;

    std::cout << "Box/Frustum outside test : " << std::flush;
    std::cout << (boxOut.intersect(frustum) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Box/Frustum inside test : " << std::flush;
    std::cout << (boxIn.intersect(frustum) ? "ok" : "**BAD**") << std::endl;

    std::cout << "Sphere/Frustum outside test : " << std::flush;
    std::cout << (sphereOut.intersect(frustum) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Sphere/Frustum inside test : " << std::flush;
    std::cout << (sphereIn.intersect(frustum) ? "ok" : "**BAD**") << std::endl;


    std::cout << "Cylinder/Frustum outside test : " << std::flush;
    std::cout << (cylinderOut.intersect(frustum) ? "**BAD**" : "ok") << std::endl;

    std::cout << "Cylinder/Frustum inside test : " << std::flush;
    std::cout << (cylinderIn.intersect(frustum) ? "ok" : "**BAD**") << std::endl;

    std::cout << "Cylinder/Sphere outside test: " << std::flush;
    std::cout << (cylinderOut.intersect(sphere) ? "**BAD**" : "ok") << std::endl;

    //###VOLUME EXTENSION################################################

    std::cout << "### volume extension test ###" << std::endl;

    Pnt3f min,max;

    //Box extension

    extend(box, boxIn);
    box.getBounds(min,max);
    std::cout<< "min of the box : " <<min<<std::endl;
    std::cout<< "max of the box : " <<max<<std::endl;

    extend(box,sphere);
    box.getBounds(min,max);
    std::cout<< "min of the box : " <<min<<std::endl;
    std::cout<< "max of the box : " <<max<<std::endl;

    extend(box,cylinder);
    box.getBounds(min,max);
    std::cout<< "min of the box : " <<min<<std::endl;
    std::cout<< "max of the box : " <<max<<std::endl;

    //Sphere extension

    extend(sphere, box);
    std::cout<<"Center of the sphere : " <<sphere.getCenter()<<std::endl;
    std::cout<<"Radius of the sphere : " <<sphere.getRadius()<<std::endl;

    extend(sphere, sphereOut);
    std::cout<<"Center of the sphere : " <<sphere.getCenter()<<std::endl;
    std::cout<<"Radius of the sphere : " <<sphere.getRadius()<<std::endl;

    extend(sphere, cylinder);
    std::cout<<"Center of the sphere : " <<sphere.getCenter()<<std::endl;
    std::cout<<"Radius of the sphere : " <<sphere.getRadius()<<std::endl;

    //Cylinder extension

    extend (cylinder, box);
    cylinder.getBounds(min,max);
    std::cout<< "min of the cylinder : " <<min<<std::endl;
    std::cout<< "max of the cylinder : " <<max<<std::endl;

    extend (cylinder, sphere);
    cylinder.getBounds(min,max);
    std::cout<< "min of the cylinder : " <<min<<std::endl;
    std::cout<< "max of the cylinder : " <<max<<std::endl;

    extend (cylinder, cylinder);
    cylinder.getBounds(min,max);
    std::cout<< "min of the cylinder : " <<min<<std::endl;
    std::cout<< "max of the cylinder : " <<max<<std::endl;


    return 0;


}
Ejemplo n.º 23
0
OSG_BASE_DLLMAPPING 
void extend(CylinderVolume &srcVol, const BoxVolume &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
        {
            vol.getBounds(min, max);

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

            adir = Vec3f(0.f, 0.f, max.z() - min.z());
            apos = Pnt3f(p.x(), p.y(), min.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;
}
Ejemplo n.º 24
0
void selectedNodeChanged(void)
{
    mgr->setHighlight(SelectedNode);


    //Update Details Panel
    if(SelectedNode == NULL)
    {
        NodeNameValueLabel->setText("");

        NodeCoreTypeValueLabel->setText("");

        NodeMinValueLabel->setText("");

        NodeMaxValueLabel->setText("");

        NodeCenterValueLabel->setText("");

        NodeTriCountValueLabel->setText("");

        NodeTravMaskValueLabel->setText("");

        NodeOcclusionMaskValueLabel->setText("");

        NodeActiveValueLabel->setText("");

    }
    else
    {
        const Char8 *NodeName = getName(SelectedNode);
        if(NodeName == NULL)
        {
            NodeNameValueLabel->setText("Unnamed Node");
        }
        else
        {
            NodeNameValueLabel->setText(NodeName);
        }

        NodeCoreTypeValueLabel->setText(SelectedNode->getCore()->getType().getCName());

        BoxVolume DyVol;
        SelectedNode->getWorldVolume(DyVol);
        Pnt3f Min,Max,Center;
        DyVol.getBounds(Min,Max);
        DyVol.getCenter(Center);

        std::string TempText("");

        TempText = boost::lexical_cast<std::string>(Min.x()) + ", " +boost::lexical_cast<std::string>(Min.x()) + ", " + boost::lexical_cast<std::string>(Min.x());
        NodeMinValueLabel->setText(TempText);

        TempText = boost::lexical_cast<std::string>(Max.x()) + ", " +boost::lexical_cast<std::string>(Max.x()) + ", " + boost::lexical_cast<std::string>(Max.x());
        NodeMaxValueLabel->setText(TempText);

        TempText = boost::lexical_cast<std::string>(Center.x()) + ", " +boost::lexical_cast<std::string>(Center.x()) + ", " + boost::lexical_cast<std::string>(Center.x());
        NodeCenterValueLabel->setText(TempText);

        //GeometryPrimitivesCounter PrimCounter;
        //PrimCounter(SelectedNode);
        //NodeTriCountValueLabel->setText(boost::lexical_cast<std::string>(PrimCounter.getTriCount()));

        //NodeTravMaskValueLabel->setText(boost::lexical_cast<std::string>(SelectedNode->getTravMask()));

        //NodeOcclusionMaskValueLabel->setText(boost::lexical_cast<std::string>(SelectedNode->getOcclusionMask()));

        //NodeActiveValueLabel->setText(boost::lexical_cast<std::string>(SelectedNode->getActive()));
    }


}