コード例 #1
0
ファイル: WriterNodeVisitor.cpp プロジェクト: artoolkit/osg
void WriterNodeVisitor::apply( osg::Geode &node )
{
    pushStateSet(node.getStateSet());
    //_nameStack.push_back(node.getName());
    unsigned int count = node.getNumDrawables();
    ListTriangle listTriangles;
    bool texcoords = false;
    for ( unsigned int i = 0; i < count; i++ )
    {
        osg::Geometry *g = node.getDrawable( i )->asGeometry();
        if ( g != NULL )
        {
            pushStateSet(g->getStateSet());
            createListTriangle(g, listTriangles, texcoords, i);        // May set _succeded to false
            popStateSet(g->getStateSet());
            if (!succeeded()) break;
        }
    }
    if (succeeded() && count > 0)
    {
#if DISABLE_3DS_ANIMATION
        osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) );
        buildFaces(node, mat, listTriangles, texcoords);        // May set _succeded to false
#else
        buildFaces(node, osg::Matrix(), listTriangles, texcoords);        // May set _succeded to false
#endif
    }
    popStateSet(node.getStateSet());
    //_nameStack.pop_back();
    if (succeeded())
        traverse(node);
}
コード例 #2
0
ファイル: osgconv.cpp プロジェクト: 3dcl/osg
    virtual void apply(osg::Geode& node)
    {
        if (node.getStateSet()) isTransparent(*node.getStateSet());

        for(unsigned int i=0;i<node.getNumDrawables();++i)
        {
            osg::Drawable* drawable = node.getDrawable(i);
            if (drawable && drawable->getStateSet()) isTransparent(*drawable->getStateSet());
        }

        traverse(node);
    }
コード例 #3
0
void StatsVisitor::apply(osg::Geode &node)
{
    if (node.getStateSet())
    {
        apply(*node.getStateSet());
    }

    ++_numInstancedGeode;
    _geodeSet.insert(&node);

    traverse(node);
}
コード例 #4
0
void OBJWriterNodeVisitor::apply( osg::Geode &node )
{
    pushStateSet(node.getStateSet());
    _nameStack.push_back(node.getName());
    unsigned int count = node.getNumDrawables();
    for ( unsigned int i = 0; i < count; i++ )
    {
        node.getDrawable( i )->accept(*this);
    }

    popStateSet(node.getStateSet());
    _nameStack.pop_back();
}
コード例 #5
0
ファイル: osgvertexattributes.cpp プロジェクト: 3dcl/osg
        void apply(osg::Geode& geode)
        {
            if (_visited.count(&geode)!=0) return;
            _visited.insert(&geode);

            if (geode.getStateSet()) apply(*(geode.getStateSet()));

            for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
            {
                if (geode.getDrawable(i)->getStateSet()) apply(*(geode.getDrawable(i)->getStateSet()));

                osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
                if (geom) apply(*geom);
            }
        }
コード例 #6
0
ファイル: ShaderGenerator.cpp プロジェクト: ReWeb3D/osgearth
void 
ShaderGenerator::apply( osg::Geode& geode )
{
    osg::ref_ptr<osg::StateSet> ss = geode.getStateSet();
    if ( ss.valid() )
    {
        _state->pushStateSet( ss.get() );

        osg::ref_ptr<osg::StateSet> replacement;
        if ( processGeometry(ss.get(), replacement) )
        {
            _state->popStateSet();
            geode.setStateSet( replacement.get() );
            _state->pushStateSet( replacement.get() );
        }
    }

    for( unsigned d = 0; d < geode.getNumDrawables(); ++d )
    {
        apply( geode.getDrawable(d) );
    }

    if ( ss.valid() )
    {
        _state->popStateSet();
    }
}
コード例 #7
0
ファイル: ShaderGenerator.cpp プロジェクト: flybpc/osgearth
void 
ShaderGenerator::apply( osg::Geode& geode )
{
    if ( !_active ) return;

    if ( geode.getStateSet() )
        _state->pushStateSet( geode.getStateSet() );

    for( unsigned d = 0; d < geode.getNumDrawables(); ++d )
    {
        apply( geode.getDrawable(d) );
    }

    if ( geode.getStateSet() )
        _state->popStateSet();
}
コード例 #8
0
void 
ShaderGenerator::apply( osg::Geode& geode )
{
    if ( !_active ) return;

    osg::ref_ptr<osg::StateSet> ss = geode.getStateSet();
    if ( ss.valid() )
    {
        _state->pushStateSet( ss.get() );

        osg::ref_ptr<osg::StateSet> replacement;
        if ( processGeometry(ss.get(), replacement) )
        {
            _state->popStateSet();
            
            // optimize state set sharing
            if ( _stateSetCache.valid() )
                _stateSetCache->share(replacement, replacement);

            geode.setStateSet( replacement.get() );

            _state->pushStateSet( replacement.get() );
        }
    }

    for( unsigned d = 0; d < geode.getNumDrawables(); ++d )
    {
        apply( geode.getDrawable(d) );
    }

    if ( ss.valid() )
    {
        _state->popStateSet();
    }
}
コード例 #9
0
ファイル: Statistics.cpp プロジェクト: AndreyIstomin/osg
void StatsVisitor::apply(osg::Geode& node)
{
    if (node.getStateSet())
    {
        apply(*node.getStateSet());
    }

    ++_numInstancedGeode;
    _geodeSet.insert(&node);

    for(unsigned int i=0; i<node.getNumDrawables();++i)
    {
        apply(*node.getDrawable(i));
    }

    traverse(node);
}
コード例 #10
0
ファイル: ch7_6.cpp プロジェクト: ghub/osg3bg
 virtual void apply(osg::Geode& geode)
 {
     replaceTexure(geode.getStateSet());
     for (unsigned int i = 0; i < geode.getNumDrawables(); ++i)
     {
         replaceTexure(geode.getDrawable(i)->getStateSet());
     }
     traverse(geode);
 }
コード例 #11
0
ファイル: osgconv.cpp プロジェクト: 3dcl/osg
    virtual void apply(osg::Geode& node)
    {
        if (node.getStateSet())
        {
            node.setStateSet(0);
            ++_numStateSetRemoved;
        }

        traverse(node);
    }
コード例 #12
0
 virtual void apply(osg::Geode& geode)
 {
     apply(geode.getStateSet());
     for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
     {
         apply(geode.getDrawable(i)->getStateSet());
         osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
         if (geometry) apply(geometry);
     }
 }
コード例 #13
0
void GLObjectsVisitor::apply(osg::Geode& node)
{
    if (node.getStateSet())
    {
        apply(*(node.getStateSet()));
    }

    for(unsigned int i=0;i<node.getNumDrawables();++i)
    {
        osg::Drawable* drawable = node.getDrawable(i);
        if (drawable)
        {
            apply(*drawable);
            if (drawable->getStateSet())
            {
                apply(*(drawable->getStateSet()));
            }
        }
    }
}
コード例 #14
0
void ProtectTransparencyVisitor::apply( osg::Geode& geode )
{
    protectTransparent( geode.getStateSet() );

    unsigned int idx;
    for( idx=0; idx<geode.getNumDrawables(); idx++ )
    {
        protectTransparent( geode.getDrawable( idx )->getStateSet() );
    }

    traverse( geode );
}
コード例 #15
0
ファイル: GLObjectsVisitor.cpp プロジェクト: aoighost/osg
void GLObjectsVisitor::apply(osg::Geode& node)
{
    bool programSetBefore = _lastCompiledProgram.valid();

    if (node.getStateSet())
    {
        apply(*(node.getStateSet()));
    }

    traverse(node);

    bool programSetAfter = _lastCompiledProgram.valid();
    if (!programSetBefore && programSetAfter)
    {
        osg::State* state = _renderInfo.getState();
        osg::GLExtensions* extensions = state->get<osg::GLExtensions>();
        extensions->glUseProgram(0);
        state->setLastAppliedProgramObject(0);
        _lastCompiledProgram = 0;
    }
}
コード例 #16
0
 void                            apply( osg::Geode& node )
                                 {
                                     node.compileDrawables( *_p_state );
                                     osg::Geode::DrawableList drawableList = node.getDrawableList();
                                     int listsize = drawableList.size();
                                     for ( int cnt = 0; cnt < listsize; ++cnt )
                                     {
                                         ++_numVisited;
                                         compileResource( node.getStateSet() );
                                     }
                                     traverse( node );
                                 }
コード例 #17
0
void DXFWriterNodeVisitor::apply( osg::Geode &node )
{

    pushStateSet(node.getStateSet());
    osg::Matrix m = osg::computeLocalToWorld(getNodePath());
    unsigned int count = node.getNumDrawables();

    for ( unsigned int i = 0; i < count; i++ )
    {
        osg::Geometry *g = node.getDrawable( i )->asGeometry();
        if ( g != NULL )
        {
            pushStateSet(g->getStateSet());
            processGeometry(g,m);
            popStateSet(g->getStateSet());
        }
    }


    popStateSet(node.getStateSet());
}
コード例 #18
0
ファイル: scenemanager.cpp プロジェクト: HolyWraith/openmw
        virtual void apply(osg::Geode& geode)
        {
            osg::StateSet* stateset = geode.getStateSet();
            if (stateset)
                applyStateSet(stateset);

            for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
            {
                osg::Drawable* drw = geode.getDrawable(i);
                stateset = drw->getStateSet();
                if (stateset)
                    applyStateSet(stateset);
            }
        }
コード例 #19
0
void
CountsVisitor::apply(osg::Geode& node)
{
    pushStateSet(node.getStateSet());

    _geodes++;
    osg::ref_ptr<osg::Object> rp = (osg::Object*)&node;
    _uGeodes.insert(rp);
    apply(node.getStateSet());

    unsigned int idx;
    for (idx=0; idx<node.getNumDrawables(); idx++)
    {
        osg::Drawable* draw = node.getDrawable(idx);
        apply(draw);
    }

    if (++_depth > _maxDepth)
        _maxDepth = _depth;
    traverse((osg::Node&)node);
    _depth--;

    popStateSet();
}
コード例 #20
0
    virtual void apply(osg::Geode& geode)
    {
        apply(geode.getStateSet());
        for(unsigned int i = 0; i < geode.getNumDrawables(); ++i)
        {
            osg::Drawable* drawable = geode.getDrawable(i);

            apply(drawable->getStateSet());
            ImageStreamStateCallback* cb = dynamic_cast<ImageStreamStateCallback*>(drawable->getUpdateCallback());
            if (cb)
                cb->setImageStream(dynamic_cast<osg::ImageStream*>(_tex->getImage(0)));

        }

        osg::NodeVisitor::apply(geode);
    }
コード例 #21
0
        /**
         * Searches a geode for drawables containing texture coordinates.
         * Based on which texture units the coordinates are mapped to,
         * appropriate texture slots are extracted.
         * @param geode The geometry node to check.
         */
        virtual void apply(osg::Geode &geode)
        {
            FindTextures(geode.getStateSet());
            for (unsigned int i=0; i<geode.getNumDrawables(); i++)
            {
                osg::Geometry *geom = geode.getDrawable(i)->asGeometry();
                if (geom != NULL)
                {
                    FindTextures(geom->getStateSet());
                    unsigned int texCoordCount = geom->getNumTexCoordArrays();
                    if (texCoordCount > mMaxTexCoordArrayCount)
                        mMaxTexCoordArrayCount = texCoordCount;
                }
            }

            traverse(geode);
        }
コード例 #22
0
void SharedStateManager::apply(osg::Geode &geode)
{
    osg::StateSet *ss = geode.getStateSet();

    if (ss)
        process(ss, &geode);

    for (unsigned int i = 0; i < geode.getNumDrawables(); ++i)
    {
        osg::Drawable *drawable = geode.getDrawable(i);
        if (drawable)
        {
            ss = drawable->getStateSet();
            if (ss)
                process(ss, drawable);
        }
    }
}
コード例 #23
0
ファイル: MeshFlattener.cpp プロジェクト: speakfool/osgearth
void FlattenSceneGraphVisitor::apply(osg::Geode& geode)
{
    osg::Billboard* billboard = dynamic_cast< osg::Billboard* >(&geode);
    // Special case, skip billboards since we can't cluster them.
    if (billboard)
    {
        return;
    }

    osg::ref_ptr< osg::StateSet > ss = geode.getStateSet();
    if (ss)
    {
        pushStateSet(ss.get());
    }

    for (unsigned int i = 0; i < geode.getNumDrawables(); i++)
    {
        osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
        if (geometry)
        {
            osg::ref_ptr< osg::StateSet > geomSS = geometry->getStateSet();
            if (geomSS.get())
            {
                pushStateSet( geomSS.get() );
            }

            GeometryVector& geometries = _geometries[_ssStack];
            geometries.push_back(geometry);

            if (geomSS.get())
            {
                popStateSet();
            }


        }
    }

    if (ss)
    {
        popStateSet();
    }

}
コード例 #24
0
ファイル: osgconv.cpp プロジェクト: AndreyIstomin/osg
    virtual void apply(osg::Geode& node)
    {
        if (node.getStateSet())
        {
            node.setStateSet(0);
            ++_numStateSetRemoved;
        }

        for(unsigned int i=0;i<node.getNumDrawables();++i)
        {
            osg::Drawable* drawable = node.getDrawable(i);
            if (drawable && drawable->getStateSet())
            {
                drawable->setStateSet(0);
                ++_numStateSetRemoved;
            }
        }

        traverse(node);
    }
コード例 #25
0
void
CountStateSets::apply( osg::Geode& node )
{
    if( !processStateSet( node.getStateSet() ) && _removeEmptyStateSets )
    {
        node.setStateSet( NULL );
        _removedStateSets++;
    }

    unsigned int idx;
    for( idx=0; idx<node.getNumDrawables(); idx++ )
    {
        osg::Drawable* draw = node.getDrawable( idx );
        if( !processStateSet( draw->getStateSet() ) && _removeEmptyStateSets )
        {
            draw->setStateSet( NULL );
            _removedStateSets++;
        }
    }

    traverse( node );
}
コード例 #26
0
void GLES2ShaderGenVisitor::apply(osg::Geode &geode)
{
    osg::StateSet *stateSet = geode.getStateSet();
    if (stateSet)
        _state->pushStateSet(stateSet);
    
    for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
    {
        osg::Drawable *drawable = geode.getDrawable(i);
        osg::StateSet *ss = drawable->getStateSet();
        if (ss)
            _state->pushStateSet(ss);
        
        update(drawable);
        
        if (ss)
            _state->popStateSet();
    }
    
    if (stateSet)
        _state->popStateSet();
}
コード例 #27
0
ファイル: CullingUtils.cpp プロジェクト: myemail2235/osgearth
void 
ProxyCullVisitor::apply(osg::Geode& node)
{
    //OE_INFO << "Geode!" << std::endl;

    if ( isCulledByProxyFrustum(node) )
        return;

    _cv->pushOntoNodePath( &node );

    // push the node's state.
    osg::StateSet* node_state = node.getStateSet();
    if (node_state) _cv->pushStateSet(node_state);

    // traverse any call callbacks and traverse any children.
    handle_cull_callbacks_and_traverse(node);

    osg::RefMatrix& matrix = *_cv->getModelViewMatrix();
    for(unsigned int i=0;i<node.getNumDrawables();++i)
    {
        osg::Drawable* drawable = node.getDrawable(i);
        const osg::BoundingBox& bb =drawable->getBound();

        if( drawable->getCullCallback() )
        {
            if( drawable->getCullCallback()->cull( _cv, drawable, &_cv->getRenderInfo() ) == true )
                continue;
        }

        //else
        {
            if (node.isCullingActive() && isCulledByProxyFrustum(bb)) continue;
        }


        if ( _cv->getComputeNearFarMode() && bb.valid())
        {
            if (!_cv->updateCalculatedNearFar(matrix,*drawable,false)) continue;
        }

        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.
        osg::StateSet* stateset = drawable->getStateSet();
        if (stateset)
        {
            ++numPopStateSetRequired;
            _cv->pushStateSet(stateset);
        }

        osg::CullingSet& cs = _cv->getCurrentCullingSet();
        if (!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                itr != sfl.end();
                ++itr)
            {
                if (itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    _cv->pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;

        if (osg::isNaN(depth))
        {
            for (osg::NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
            {
                OSG_DEBUG << "        \"" << (*i)->getName() << "\"" << std::endl;
            }
        }
        else
        {
            _cv->addDrawableAndDepth(drawable,&matrix,depth);
        }

        for(unsigned int i=0;i< numPopStateSetRequired; ++i)
        {
            _cv->popStateSet();
        }

    }

    // pop the node's state off the geostate stack.
    if (node_state) _cv->popStateSet();

    _cv->popFromNodePath();
}
コード例 #28
0
void 
ShaderGenerator::apply( osg::Geode& node )
{
    if ( !_active )
        return;

    if ( ignore(&node) )
        return;
    
    if ( _duplicateSharedSubgraphs )
        duplicateSharedNode(node);

    osg::ref_ptr<osg::StateSet> stateset = node.getStateSet();
    if ( stateset.valid() )
    {
        _state->pushStateSet( stateset.get() );
    }

    unsigned numDrawables = node.getNumDrawables();
    bool traverseDrawables = true;

#ifdef PROMOTE_EQUIVALENT_DRAWABLE_VP_TO_GEODE
    // This block checks whether all the geode's drawables are equivalent,
    // i.e., they are the same type (geometry or text) and none of them
    // have their own state sets. IF that's the case, we can create a 
    // single shader program for the entire geode. This is an optimization.
    if ( stateset.valid() )
    {
        unsigned d;
        unsigned numInheritingText = 0, numInheritingGeometry = 0;
        for( d = 0; d < numDrawables; ++d )
        {
            osg::Drawable* drawable = node.getDrawable(d);
            if ( drawable->getStateSet() == 0L )
            {
                if ( drawable->asGeometry() )
                    numInheritingGeometry++;
                else if ( dynamic_cast<osgText::Text*>(drawable) )
                    numInheritingText++;
            }
        }

        if (numInheritingGeometry == numDrawables )
        {
            osg::ref_ptr<osg::StateSet> replacement;
            if ( processGeometry(stateset.get(), replacement) )
            {
                node.setStateSet(replacement.get() );
                traverseDrawables = false;
            }
        }
        else if (numInheritingText == numDrawables )
        {
            osg::ref_ptr<osg::StateSet> replacement;
            if ( processText(stateset.get(), replacement) )
            {
                node.setStateSet(replacement.get() );
                traverseDrawables = false;
            }
        }
    }
#endif

    // Drawables have state sets, so let's traverse them.
    if ( traverseDrawables )
    {
        for( unsigned d = 0; d < node.getNumDrawables(); ++d )
        {
            apply( node.getDrawable(d) );
        }
    }

    if ( stateset.valid() )
    {
        _state->popStateSet();
    }
}
コード例 #29
0
ファイル: CVRCullVisitor.cpp プロジェクト: megasha/calvr
void CVRCullVisitor::apply(osg::Geode& node)
{
    bool status = _cullingStatus;
    bool firstStatus = _firstCullStatus;
    if(isCulled(node))
    {
        _firstCullStatus = firstStatus;
        _cullingStatus = status;
        return;
    }

    // push the node's state.
    StateSet* node_state = node.getStateSet();
    if(node_state)
        pushStateSet(node_state);

    // traverse any call callbacks and traverse any children.
    handle_cull_callbacks_and_traverse(node);

    RefMatrix& matrix = *getModelViewMatrix();
    for(unsigned int i = 0; i < node.getNumDrawables(); ++i)
    {
        Drawable* drawable = node.getDrawable(i);
        const BoundingBox &bb = drawable->getBound();

        if(drawable->getCullCallback())
        {
            if(drawable->getCullCallback()->cull(this,drawable,&_renderInfo)
                    == true)
                continue;
        }

        //else
        {
            if(node.isCullingActive() && isCulled(bb))
                continue;
        }

        if(_computeNearFar && bb.valid())
        {
            if(!updateCalculatedNearFar(matrix,*drawable,false))
                continue;
        }

        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.    
        StateSet* stateset = drawable->getStateSet();
        if(stateset)
        {
            ++numPopStateSetRequired;
            pushStateSet(stateset);
        }

        CullingSet& cs = getCurrentCullingSet();
        if(!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                    itr != sfl.end(); ++itr)
            {
                if(itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;

        if(osg::isNaN(depth))
        {
            /*OSG_NOTIFY(osg::NOTICE)<<"CullVisitor::apply(Geode&) detected NaN,"<<std::endl
             <<"    depth="<<depth<<", center=("<<bb.center()<<"),"<<std::endl
             <<"    matrix="<<matrix<<std::endl;
             OSG_NOTIFY(osg::DEBUG_INFO) << "    NodePath:" << std::endl;
             for (NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
             {
             OSG_NOTIFY(osg::DEBUG_INFO) << "        \"" << (*i)->getName() << "\"" << std::endl;
             }*/
        }
        else
        {
            addDrawableAndDepth(drawable,&matrix,depth);
        }

        for(unsigned int i = 0; i < numPopStateSetRequired; ++i)
        {
            popStateSet();
        }

    }

    // pop the node's state off the geostate stack.    
    if(node_state)
        popStateSet();

    _firstCullStatus = firstStatus;
    _cullingStatus = status;
}
コード例 #30
0
ファイル: FltExportVisitor.cpp プロジェクト: joevandyk/osg
// Billboards also go through this code. The Geode is passed
// to writeFace and writeMesh. If those methods successfully cast
// the Geode to a Billboard, then they set the template mode
// bit accordingly.
void
FltExportVisitor::apply( osg::Geode& node )
{
    _firstNode = false;
    ScopedStatePushPop guard( this, node.getStateSet() );

    unsigned int idx;
    for (idx=0; idx<node.getNumDrawables(); idx++)
    {
        osg::Geometry* geom = node.getDrawable( idx )->asGeometry();
        if (!geom)
        {
            std::string warning( "fltexp: Non-Geometry Drawable encountered. Ignoring." );
            osg::notify( osg::WARN ) << warning << std::endl;
            _fltOpt->getWriteResult().warn( warning );
            continue;
        }

        ScopedStatePushPop drawableGuard( this, geom->getStateSet() );

        // Push and pop subfaces if polygon offset is on.
        SubfaceHelper subface( *this, getCurrentStateSet() );

        if (atLeastOneFace( *geom ))
        {
            // If at least one record will be a Face record, then we
            //   need to write to the vertex palette.
            _vertexPalette->add( *geom );

            // Iterate over all PrimitiveSets and output Face records.
            unsigned int jdx;
            for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++)
            {
                osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx );
                if ( isMesh( prim->getMode() ) )
                    continue;

                if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType)
                    handleDrawArrays( dynamic_cast<osg::DrawArrays*>( prim ), *geom, node );
                else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
                    handleDrawArrayLengths( dynamic_cast<osg::DrawArrayLengths*>( prim ), *geom, node );
                else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) )
                    handleDrawElements( dynamic_cast<osg::DrawElements*>( prim ), *geom, node );
                else
                {
                    std::string warning( "fltexp: Unknown PrimitiveSet type." );
                    osg::notify( osg::WARN ) << warning << std::endl;
                    _fltOpt->getWriteResult().warn( warning );
                    return;
                }
            }
        }

        if (atLeastOneMesh( *geom ))
        {
            // If at least one Mesh record, write out preamble mesh records
            //   followed by a Mesh Primitive record per PrimitiveSet.
            writeMesh( node, *geom );

            writeMatrix( node.getUserData() );
            writeComment( node );
            writeMultitexture( *geom );
            writeLocalVertexPool( *geom );

            writePush();

            unsigned int jdx;
            for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++)
            {
                osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx );
                if ( !isMesh( prim->getMode() ) )
                    continue;

                if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType)
                    handleDrawArrays( dynamic_cast<osg::DrawArrays*>( prim ), *geom, node );
                else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
                    handleDrawArrayLengths( dynamic_cast<osg::DrawArrayLengths*>( prim ), *geom, node );
                else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) )
                    handleDrawElements( dynamic_cast<osg::DrawElements*>( prim ), *geom, node );
                else
                {
                    std::string warning( "fltexp: Unknown PrimitiveSet type." );
                    osg::notify( osg::WARN ) << warning << std::endl;
                    _fltOpt->getWriteResult().warn( warning );
                    return;
                }
            }

            writePop();
        }
    }

    // Would traverse here if this node could have children.
    //   traverse( (osg::Node&)node );
}