Beispiel #1
0
        void apply(osg::Geometry& geom)
        {
            geom.setUseDisplayList(false);

            if (!_manualVertexAliasing) return;

            osg::notify(osg::NOTICE)<<"Found geometry "<<&geom<<std::endl;
            if (geom.getVertexArray())
            {
                setVertexAttrib(geom, _vertexAlias, geom.getVertexArray(), false, osg::Array::BIND_PER_VERTEX);
                geom.setVertexArray(0);
            }

            if (geom.getNormalArray())
            {
                setVertexAttrib(geom, _normalAlias, geom.getNormalArray(), true);
                geom.setNormalArray(0);
            }

            if (geom.getColorArray())
            {
                setVertexAttrib(geom, _colorAlias, geom.getColorArray(), false);
                geom.setColorArray(0);
            }

            if (geom.getSecondaryColorArray())
            {
                setVertexAttrib(geom, _secondaryColorAlias, geom.getSecondaryColorArray(), false);
                geom.setSecondaryColorArray(0);
            }

            if (geom.getFogCoordArray())
            {
                // should we normalize the FogCoord array? Don't think so...
                setVertexAttrib(geom, _fogCoordAlias, geom.getFogCoordArray(), false);
                geom.setFogCoordArray(0);
            }

            unsigned int maxNumTexCoords = geom.getNumTexCoordArrays();
            if (maxNumTexCoords>8)
            {
                osg::notify(osg::NOTICE)<<"Warning: Ignoring "<<maxNumTexCoords-8<<" texture coordinate arrays, only 8 are currently supported in vertex attribute conversion code."<<std::endl;
                maxNumTexCoords = 8;
            }
            for(unsigned int i=0; i<maxNumTexCoords; ++i)
            {
                if (geom.getTexCoordArray(i))
                {
                    setVertexAttrib(geom, _texCoordAlias[i], geom.getTexCoordArray(i), false, osg::Array::BIND_PER_VERTEX);
                    geom.setTexCoordArray(i,0);
                }
                else
                {
                    osg::notify(osg::NOTICE)<<"Found empty TexCoordArray("<<i<<")"<<std::endl;
                }
            }
        }
Beispiel #2
0
void RigGeometry::copyFrom(osg::Geometry& from)
{
    bool copyToSelf = (this==&from);

    osg::Geometry& target = *this;

    if (!copyToSelf) target.setStateSet(from.getStateSet());

    // copy over primitive sets.
    if (!copyToSelf) target.getPrimitiveSetList() = from.getPrimitiveSetList();

    if (from.getVertexArray())
    {
        if (!copyToSelf) target.setVertexArray(from.getVertexArray());
    }

    if (from.getNormalArray())
    {
        if (!copyToSelf) target.setNormalArray(from.getNormalArray());
    }

    if (from.getColorArray())
    {
        if (!copyToSelf) target.setColorArray(from.getColorArray());
    }

    if (from.getSecondaryColorArray())
    {
        if (!copyToSelf) target.setSecondaryColorArray(from.getSecondaryColorArray());
    }

    if (from.getFogCoordArray())
    {
        if (!copyToSelf) target.setFogCoordArray(from.getFogCoordArray());
    }

    for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti)
    {
        if (from.getTexCoordArray(ti))
        {
            if (!copyToSelf) target.setTexCoordArray(ti,from.getTexCoordArray(ti));
        }
    }

    osg::Geometry::ArrayList& arrayList = from.getVertexAttribArrayList();
    for(unsigned int vi=0;vi< arrayList.size();++vi)
    {
        osg::Array* array = arrayList[vi].get();
        if (array)
        {
            if (!copyToSelf) target.setVertexAttribArray(vi,array);
        }
    }
}
void
FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom )
{
    unsigned int numLayers( 0 );
    uint32 flags( 0 );
    unsigned int idx;
    for( idx=1; idx<8; idx++)
    {
        if( isTextured( idx, geom ) )
        {
            flags |= LAYER_1 >> (idx-1);
            numLayers++;
        }
    }
    if( numLayers == 0 )
        return;

    uint16 length( 8 + (8*numLayers*numVerts) );

    _records->writeInt16( (int16) UV_LIST_OP );
    _records->writeUInt16( length );
    _records->writeInt32( flags );

    osg::Vec2 defaultCoord( 0., 0. );
    // const osg::StateSet* ss = getCurrentStateSet();
    for( idx=1; idx<8; idx++)
    {
        if( isTextured( idx, geom ) )
        {
            osg::Array* t = const_cast<osg::Array*>( geom.getTexCoordArray( idx ) );
            osg::ref_ptr<osg::Vec2Array> t2 = dynamic_cast<osg::Vec2Array*>( t );
            if (!t2.valid())
            {
                std::ostringstream warning;
                warning << "fltexp: No Texture2D for unit " << idx;
                osg::notify( osg::WARN ) << warning.str() << std::endl;
                _fltOpt->getWriteResult().warn( warning.str() );
                t2 = new osg::Vec2Array;
            }
            else if (static_cast<int>(t2->getNumElements()) != numVerts)
            {
                std::ostringstream warning;
                warning << "fltexp: Invalid number of texture coordinates for unit " << idx;
                osg::notify( osg::WARN ) << warning.str() << std::endl;
                _fltOpt->getWriteResult().warn( warning.str() );
            }

            const int size = t2->getNumElements();
            int vIdx;
            for( vIdx=0; vIdx<numVerts; vIdx++)
            {
                osg::Vec2& tc( defaultCoord );
                if (vIdx < size)
                    tc = (*t2)[ vIdx ];
                _records->writeFloat32( tc[0] );
                _records->writeFloat32( tc[1] );
            }
        }
    }
}
    void ShaderVisitor::apply(osg::Geometry& geometry)
    {
        bool needPop = (geometry.getStateSet() != NULL);
        if (geometry.getStateSet())
        {
            pushRequirements();
            applyStateSet(geometry.getStateSet(), geometry);
        }

        if (!mRequirements.empty())
        {
            const ShaderRequirements& reqs = mRequirements.back();

            if (mAllowedToModifyStateSets)
            {
                // make sure that all UV sets are there
                for (std::map<int, std::string>::const_iterator it = reqs.mTextures.begin(); it != reqs.mTextures.end(); ++it)
                {
                    if (geometry.getTexCoordArray(it->first) == NULL)
                        geometry.setTexCoordArray(it->first, geometry.getTexCoordArray(0));
                }
            }

            if (reqs.mTexStageRequiringTangents != -1 && mAllowedToModifyStateSets)
            {
                osg::ref_ptr<osgUtil::TangentSpaceGenerator> generator (new osgUtil::TangentSpaceGenerator);
                generator->generate(&geometry, reqs.mTexStageRequiringTangents);

                geometry.setTexCoordArray(7, generator->getTangentArray(), osg::Array::BIND_PER_VERTEX);
            }

            // TODO: find a better place for the stateset
            if (reqs.mShaderRequired || mForceShaders)
                createProgram(reqs, geometry);
        }

        if (needPop)
            popRequirements();
    }
Beispiel #5
0
 VertexAttribComparitor(osg::Geometry& geometry)
 {
     add(geometry.getVertexArray());
     add(geometry.getNormalArray());
     add(geometry.getColorArray());
     add(geometry.getSecondaryColorArray());
     add(geometry.getFogCoordArray());
     unsigned int i;
     for(i=0;i<geometry.getNumTexCoordArrays();++i)
     {
         add(geometry.getTexCoordArray(i));
     }
     for(i=0;i<geometry.getNumVertexAttribArrays();++i)
     {
         add(geometry.getVertexAttribArray(i));
     }
 }
void
FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom )
{
    // Attribute Mask
    static const unsigned int HAS_POSITION      = 0x80000000u >> 0;
    // static const unsigned int HAS_COLOR_INDEX   = 0x80000000u >> 1;
    static const unsigned int HAS_RGBA_COLOR    = 0x80000000u >> 2;
    static const unsigned int HAS_NORMAL        = 0x80000000u >> 3;
    static const unsigned int HAS_BASE_UV       = 0x80000000u >> 4;
    static const unsigned int HAS_UV_LAYER1     = 0x80000000u >> 5;
    static const unsigned int HAS_UV_LAYER2     = 0x80000000u >> 6;
    static const unsigned int HAS_UV_LAYER3     = 0x80000000u >> 7;
    static const unsigned int HAS_UV_LAYER4     = 0x80000000u >> 8;
    static const unsigned int HAS_UV_LAYER5     = 0x80000000u >> 9;
    static const unsigned int HAS_UV_LAYER6     = 0x80000000u >> 10;
    static const unsigned int HAS_UV_LAYER7     = 0x80000000u >> 11;

    const osg::Array* v = geom.getVertexArray();
    uint32 numVerts( v->getNumElements() );
    osg::ref_ptr< const osg::Vec3dArray > v3 = VertexPaletteManager::asVec3dArray( v, numVerts );
    if (!v3)
    {
        std::string warning( "fltexp: writeLocalVertexPool: VertexArray is not Vec3Array." );
        osg::notify( osg::WARN ) << warning << std::endl;
        _fltOpt->getWriteResult().warn( warning );
        return;
    }

    // Compute attribute bits and vertex size.
    const osg::Array* c = geom.getColorArray();
    const osg::Array* n = geom.getNormalArray();
    const osg::Array* t = geom.getTexCoordArray( 0 );

    osg::ref_ptr< const osg::Vec4Array > c4 = VertexPaletteManager::asVec4Array( c, numVerts );
    osg::ref_ptr< const osg::Vec3Array > n3 = VertexPaletteManager::asVec3Array( n, numVerts );
    osg::ref_ptr< const osg::Vec2Array > t2 = VertexPaletteManager::asVec2Array( t, numVerts );
    if (c && !c4)
        return;
    if (n && !n3)
        return;
    if (t && !t2)
        return;

    std::vector< osg::ref_ptr< const osg::Vec2Array > > mtc;
    mtc.resize( 8 );
    int unit=1;
    for( ;unit<8; unit++)
        mtc[ unit ] = VertexPaletteManager::asVec2Array( geom.getTexCoordArray( unit ), numVerts );

    uint32 attr( HAS_POSITION );
    unsigned int vertSize( sizeof( float64 ) * 3 );

    if ( ( c4 != NULL ) && ( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) )
    {
        attr |= HAS_RGBA_COLOR;
        vertSize += sizeof( unsigned int );
    }
    if ( ( n3 != NULL ) && ( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) )
    {
        attr |= HAS_NORMAL;
        vertSize += ( sizeof( float32 ) * 3 );
    }
    if ( t2 != NULL )
    {
        attr |= HAS_BASE_UV;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    // Add multitex
    if (isTextured( 1, geom ))
    {
        attr |= HAS_UV_LAYER1;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 2, geom ))
    {
        attr |= HAS_UV_LAYER2;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 3, geom ))
    {
        attr |= HAS_UV_LAYER3;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 4, geom ))
    {
        attr |= HAS_UV_LAYER4;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 5, geom ))
    {
        attr |= HAS_UV_LAYER5;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 6, geom ))
    {
        attr |= HAS_UV_LAYER6;
        vertSize += ( sizeof( float32 ) * 2 );
    }
    if (isTextured( 7, geom ))
    {
        attr |= HAS_UV_LAYER7;
        vertSize += ( sizeof( float32 ) * 2 );
    }

    unsigned int maxVerts = (0xffff - 12) / vertSize;
    unsigned int thisVertCount = (maxVerts > numVerts) ? numVerts : maxVerts;
    unsigned int currentIndexLimit = maxVerts;
    uint16 length( 12 + (vertSize * thisVertCount) );


    _records->writeInt16( (int16) LOCAL_VERTEX_POOL_OP );
    _records->writeUInt16( length );
    _records->writeUInt32( numVerts ); // number of vertices
    _records->writeUInt32( attr ); // attribute bits

    unsigned int idx;
    for( idx=0; idx<numVerts; idx++ )
    {
        _records->writeVec3d( (*v3)[ idx ] );

        if (attr & HAS_RGBA_COLOR)
        {
            osg::Vec4 color = (*c4)[ idx ];
            unsigned int packedColor = (int)(color[3]*255) << 24 |
                (int)(color[2]*255) << 16 | (int)(color[1]*255) << 8 |
                (int)(color[0]*255);
            _records->writeUInt32( packedColor );
        }

        if (attr & HAS_NORMAL)
            _records->writeVec3f( (*n3)[ idx ] );

        if (attr & HAS_BASE_UV)
            _records->writeVec2f( (*t2)[ idx ] );

        if (attr & HAS_UV_LAYER1)
            _records->writeVec2f( (*mtc[1])[ idx ] );
        if (attr & HAS_UV_LAYER2)
            _records->writeVec2f( (*mtc[2])[ idx ] );
        if (attr & HAS_UV_LAYER3)
            _records->writeVec2f( (*mtc[3])[ idx ] );
        if (attr & HAS_UV_LAYER4)
            _records->writeVec2f( (*mtc[4])[ idx ] );
        if (attr & HAS_UV_LAYER5)
            _records->writeVec2f( (*mtc[5])[ idx ] );
        if (attr & HAS_UV_LAYER6)
            _records->writeVec2f( (*mtc[6])[ idx ] );
        if (attr & HAS_UV_LAYER7)
            _records->writeVec2f( (*mtc[7])[ idx ] );


        // Handle continuation record if necessary.
        if ( (idx+1 == currentIndexLimit) && (idx+1 < numVerts) )
        {
            currentIndexLimit += maxVerts;
            unsigned int remaining( numVerts - (idx+1) );
            thisVertCount = (maxVerts > remaining) ? remaining : maxVerts;
            writeContinuationRecord( (vertSize * thisVertCount) );
        }
    }
}
Beispiel #7
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
}