Ejemplo n.º 1
0
void deleteFaces(osg::Geometry& geometry)
{
    geometry.removePrimitiveSet(0, geometry.getNumPrimitiveSets());

    auto _vertices = detail::getOrCreateVertexArray(geometry);
    auto _normals = detail::getOrCreateNormalArray(geometry);
    auto _colors = detail::getOrCreateColorArray(geometry);

    _vertices->clear();
    _normals->clear();
    _colors->clear();

    _vertices->dirty();
    _normals->dirty();
    _colors->dirty();
}
Ejemplo n.º 2
0
bool
Tessellator::tessellateGeometry(osg::Geometry &geom)
{
    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());

    if (!vertices || vertices->empty() || geom.getPrimitiveSetList().empty()) return false;

    // copy the original primitive set list
    osg::Geometry::PrimitiveSetList originalPrimitives = geom.getPrimitiveSetList();

    // clear the primitive sets
    unsigned int nprimsetoriginal= geom.getNumPrimitiveSets();
    if (nprimsetoriginal) geom.removePrimitiveSet(0, nprimsetoriginal);

    bool success = true;
    for (unsigned int i=0; i < originalPrimitives.size(); i++)
    {
        osg::ref_ptr<osg::PrimitiveSet> primitive = originalPrimitives[i].get();

        if (primitive->getMode()==osg::PrimitiveSet::POLYGON || primitive->getMode()==osg::PrimitiveSet::LINE_LOOP)
        {
            if (primitive->getType()==osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
            {
                osg::DrawArrayLengths* drawArrayLengths = static_cast<osg::DrawArrayLengths*>(primitive.get());
                unsigned int first = drawArrayLengths->getFirst();
                for(osg::DrawArrayLengths::iterator itr=drawArrayLengths->begin();
                    itr!=drawArrayLengths->end();
                    ++itr)
                {
                    unsigned int last = first + *itr;
                    osg::PrimitiveSet* newPrimitive = tessellatePrimitive(first, last, vertices);
                    if (newPrimitive)
                    {
                        geom.addPrimitiveSet(newPrimitive);
                    }
                    else
                    {
                        // tessellation failed, add old primitive set back
                        geom.addPrimitiveSet(primitive);
                        success = false;
                    }

                    first = last;
                }
            }
            else
            {
                if (primitive->getNumIndices()>=3)
                {
                    osg::PrimitiveSet* newPrimitive = tessellatePrimitive(primitive.get(), vertices);
                    if (newPrimitive)
                    {
                        geom.addPrimitiveSet(newPrimitive);
                    }
                    else
                    {
                        // tessellation failed, add old primitive set back
                        geom.addPrimitiveSet(primitive);
                        success = false;
                    }
                }
            }
        }
        else
        {
            //
            // TODO: handle more primitive modes
            //
        }
    }

    return success;
}
Ejemplo n.º 3
0
void Tessellator::retessellatePolygons(osg::Geometry &geom)
{
#ifdef OSG_GLU_AVAILABLE
    // turn the contour list into primitives, a little like Tessellator does but more generally
    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
    
    if (!vertices || vertices->empty() || geom.getPrimitiveSetList().empty()) return;


    // we currently don't handle geometry which use indices...
    if (geom.getVertexIndices() ||
        geom.getNormalIndices() ||
        geom.getColorIndices() ||
        geom.getSecondaryColorIndices() ||
        geom.getFogCoordIndices()) return;
        
    // not even text coord indices don't handle geometry which use indices...
    for(unsigned int unit=0;unit<geom.getNumTexCoordArrays();++unit)
    {
        if (geom.getTexCoordIndices(unit)) return;
    }

    if (_ttype==TESS_TYPE_POLYGONS || _ttype==TESS_TYPE_DRAWABLE) _numberVerts=0; // 09.04.04 GWM reset Tessellator
    // the reset is needed by the flt loader which reuses a Tessellator for triangulating polygons.
    // as such it might be reset by other loaders/developers in future.
    _index=0; // reset the counter for indexed vertices
    _extraPrimitives = 0;
    if (!_numberVerts) {
        _numberVerts=geom.getVertexArray()->getNumElements();
        // save the contours for complex (winding rule) tessellations
        _Contours=geom.getPrimitiveSetList();
    }

    // now cut out vertex attributes added on any previous tessellation
    reduceArray(geom.getVertexArray(), _numberVerts);
    reduceArray(geom.getColorArray(), _numberVerts);
    reduceArray(geom.getNormalArray(), _numberVerts);
    reduceArray(geom.getFogCoordArray(), _numberVerts);
    for(unsigned int unit1=0;unit1<geom.getNumTexCoordArrays();++unit1)
    {
        reduceArray(geom.getTexCoordArray(unit1), _numberVerts);
    }

    // remove the existing primitives.
    unsigned int nprimsetoriginal= geom.getNumPrimitiveSets();
    if (nprimsetoriginal) geom.removePrimitiveSet(0, nprimsetoriginal);

    // the main difference from osgUtil::Tessellator for Geometry sets of multiple contours is that the begin/end tessellation
    // occurs around the whole set of contours.
    if (_ttype==TESS_TYPE_GEOMETRY) {
        beginTessellation();
        gluTessProperty(_tobj, GLU_TESS_WINDING_RULE, _wtype);
        gluTessProperty(_tobj, GLU_TESS_BOUNDARY_ONLY , _boundaryOnly);
    }
    // process all the contours into the Tessellator
    int noContours = _Contours.size();
    int currentPrimitive = 0;
    for(int primNo=0;primNo<noContours;++primNo)
    {
        osg::ref_ptr<osg::PrimitiveSet> primitive = _Contours[primNo].get();
        if (_ttype==TESS_TYPE_POLYGONS || _ttype==TESS_TYPE_DRAWABLE)
        { // this recovers the 'old' tessellation which just retessellates single polygons.
            if (primitive->getMode()==osg::PrimitiveSet::POLYGON || _ttype==TESS_TYPE_DRAWABLE)
            {

                if (primitive->getType()==osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
                {
                    osg::DrawArrayLengths* drawArrayLengths = static_cast<osg::DrawArrayLengths*>(primitive.get());
                    unsigned int first = drawArrayLengths->getFirst(); 
                    for(osg::DrawArrayLengths::iterator itr=drawArrayLengths->begin();
                        itr!=drawArrayLengths->end();
                        ++itr)
                    {
                        beginTessellation();
                            unsigned int last = first + *itr;
                            addContour(primitive->getMode(),first,last,vertices);
                            first = last;
                        endTessellation();
                        collectTessellation(geom, currentPrimitive);
                        currentPrimitive++;
                    }
                }
                else
                {
                    if (primitive->getNumIndices()>3) { // April 2005 gwm only retessellate "complex" polygons
                        beginTessellation();
                        addContour(primitive.get(), vertices);
                        endTessellation();
                        collectTessellation(geom, currentPrimitive);
                        currentPrimitive++;
                    } else { // April 2005 gwm triangles don't need to be retessellated
                        geom.addPrimitiveSet(primitive.get());
                    }
                }

            }
            else
            { // copy the contour primitive as it is not being tessellated
                geom.addPrimitiveSet(primitive.get());
            }
        } else {
            if (primitive->getMode()==osg::PrimitiveSet::POLYGON ||
                primitive->getMode()==osg::PrimitiveSet::QUADS ||
                primitive->getMode()==osg::PrimitiveSet::TRIANGLES ||
                primitive->getMode()==osg::PrimitiveSet::LINE_LOOP ||
                primitive->getMode()==osg::PrimitiveSet::QUAD_STRIP ||
                primitive->getMode()==osg::PrimitiveSet::TRIANGLE_FAN ||
                primitive->getMode()==osg::PrimitiveSet::TRIANGLE_STRIP)
            {
                addContour(primitive.get(), vertices);
            } else { // copy the contour primitive as it is not being tessellated
                // in this case points, lines or line_strip
                geom.addPrimitiveSet(primitive.get());
            }
        }
    }
    if (_ttype==TESS_TYPE_GEOMETRY) {
        endTessellation();
    
        collectTessellation(geom, 0);    
    }
#endif
}