diff --git a/src/osgPlugins/OpenFlight/FltExportVisitor.cpp b/src/osgPlugins/OpenFlight/FltExportVisitor.cpp index 7ad98a469..c449b468f 100644 --- a/src/osgPlugins/OpenFlight/FltExportVisitor.cpp +++ b/src/osgPlugins/OpenFlight/FltExportVisitor.cpp @@ -356,32 +356,80 @@ FltExportVisitor::apply( osg::Geode& node ) ScopedStatePushPop drawableGuard( this, geom->getStateSet() ); - // Write vertex array data out to vertex palette manager - if (!isAllMesh( *geom )) + // 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 pool. + // need to write to the vertex palette. _vertexPalette->add( *geom ); - unsigned int jdx; - for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++) - { - osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx ); - if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType) - handleDrawArrays( dynamic_cast( prim ), *geom, node ); - else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) - handleDrawArrayLengths( dynamic_cast( prim ), *geom, node ); - else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) || - (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) || - (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) ) - handleDrawElements( dynamic_cast( prim ), *geom, node ); - else + // Iterate over all PrimitiveSets and output Face records. + unsigned int jdx; + for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++) { - std::string warning( "fltexp: Unknown PrimitiveSet type." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; + osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx ); + if ( isMesh( prim->getMode() ) ) + continue; + + if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType) + handleDrawArrays( dynamic_cast( prim ), *geom, node ); + else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) + handleDrawArrayLengths( dynamic_cast( prim ), *geom, node ); + else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) || + (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) || + (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) ) + handleDrawElements( dynamic_cast( 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( prim ), *geom, node ); + else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType) + handleDrawArrayLengths( dynamic_cast( prim ), *geom, node ); + else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) || + (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) || + (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) ) + handleDrawElements( dynamic_cast( 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. diff --git a/src/osgPlugins/OpenFlight/FltExportVisitor.h b/src/osgPlugins/OpenFlight/FltExportVisitor.h index 120d87e80..747429ba5 100644 --- a/src/osgPlugins/OpenFlight/FltExportVisitor.h +++ b/src/osgPlugins/OpenFlight/FltExportVisitor.h @@ -124,11 +124,11 @@ public: // Geometry records void writeFace( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode ); - void writeMesh( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode ); + void writeMesh( const osg::Geode& geode, const osg::Geometry& geom ); int writeVertexList( int first, unsigned int count ); int writeVertexList( const std::vector& indices, unsigned int count ); void writeMeshPrimitive( const std::vector& indices, GLenum mode ); - void writeLocalVertexPool( const osg::Geometry& geom, GLenum mode ); + void writeLocalVertexPool( const osg::Geometry& geom ); void writeMultitexture( const osg::Geometry& geom ); void writeUVList( int numVerts, const osg::Geometry& geom ); @@ -158,7 +158,9 @@ private: bool isLit( const osg::Geometry& geom ) const; bool isTextured( int unit, const osg::Geometry& geom ) const; - bool isAllMesh( const osg::Geometry& geom ) const; + bool isMesh( const GLenum mode ) const; + bool atLeastOneFace( const osg::Geometry& geom ) const; + bool atLeastOneMesh( const osg::Geometry& geom ) const; osg::ref_ptr< ExportOptions > _fltOpt; diff --git a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp index 438ad9a87..58aed9e32 100644 --- a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp @@ -67,19 +67,40 @@ FltExportVisitor::isTextured( int unit, const osg::Geometry& geom ) const } bool -FltExportVisitor::isAllMesh( const osg::Geometry& geom ) const +FltExportVisitor::isMesh( const GLenum mode ) const { - // Return true if all primitive types will use Mesh records for output. + return( (mode == GL_TRIANGLE_STRIP) || + (mode == GL_TRIANGLE_FAN) || + (mode == GL_QUAD_STRIP) ); +} + +bool +FltExportVisitor::atLeastOneFace( const osg::Geometry& geom ) const +{ + // Return true if at least one PrimitiveSet mode will use a Face record. unsigned int jdx; for (jdx=0; jdx < geom.getNumPrimitiveSets(); jdx++) { const osg::PrimitiveSet* prim = geom.getPrimitiveSet( jdx ); - if( (prim->getMode() != GL_TRIANGLE_STRIP) && - (prim->getMode() != GL_TRIANGLE_FAN) && - (prim->getMode() != GL_QUAD_STRIP) ) - return false; + if( !isMesh( prim->getMode() ) ) + return true; } - return true; + // All PrimitiveSet modes will use Mesh records. + return false; +} +bool +FltExportVisitor::atLeastOneMesh( const osg::Geometry& geom ) const +{ + // Return true if at least one PrimitiveSet mode will use a Mesh record. + unsigned int jdx; + for (jdx=0; jdx < geom.getNumPrimitiveSets(); jdx++) + { + const osg::PrimitiveSet* prim = geom.getPrimitiveSet( jdx ); + if( isMesh( prim->getMode() ) ) + return true; + } + // All PrimitiveSet modes will use Face records. + return false; } void @@ -282,7 +303,7 @@ FltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, void -FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode ) +FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom ) { enum DrawMode { @@ -354,32 +375,6 @@ FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom, int8 drawType; osg::StateSet const* ss = getCurrentStateSet(); - switch( mode ) - { - case GL_POINTS: - { - std::string warning( "fltexp: GL_POINTS not supported in FLT export." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; - break; - } - case GL_LINES: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_TRIANGLES: - case GL_QUADS: - { - std::string warning( "fltexp: Wrong mode in Mesh record." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; - break; - } - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_QUAD_STRIP: - case GL_POLYGON: { // Default to no facet culling drawType = SOLID_NO_BACKFACE; @@ -394,8 +389,6 @@ FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom, // Note: OpenFlt can't handle FRONT or FRONT_AND_BACK settings, so ignore these(??) } - break; - } } // Determine the material properties for the face @@ -544,7 +537,7 @@ FltExportVisitor::writeMeshPrimitive( const std::vector& indices, } void -FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom, GLenum mode ) +FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom ) { // Attribute Mask static const unsigned int HAS_POSITION = 0x80000000u >> 0; @@ -836,11 +829,7 @@ FltExportVisitor::handleDrawArrays( const osg::DrawArrays* da, const osg::Geomet useMesh = true; break; case GL_POINTS: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_POLYGON: - default: - n = count; + n = 1; break; case GL_LINES: n = 2; @@ -851,40 +840,27 @@ FltExportVisitor::handleDrawArrays( const osg::DrawArrays* da, const osg::Geomet case GL_QUADS: n = 4; break; + case GL_LINE_STRIP: + case GL_LINE_LOOP: + case GL_POLYGON: + default: + n = count; + break; } - // Push and pop subfaces if polygon offset is on. - SubfaceHelper subface( *this, getCurrentStateSet() ); - if (useMesh) { - writeMesh( geode, geom, mode ); - - writeMatrix( geode.getUserData() ); - writeComment( geode ); - writeMultitexture( geom ); - writeLocalVertexPool( geom, mode ); - - writePush(); - std::vector< unsigned int > indices; int jdx; for (jdx=0; jdxbegin(); itr!=dal->end(); itr++ ) @@ -959,8 +928,6 @@ FltExportVisitor::handleDrawArrayLengths( const osg::DrawArrayLengths* dal, cons indices.push_back( idx ); writeMeshPrimitive( indices, mode ); } - - writePop(); } else { @@ -1016,11 +983,7 @@ FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Ge useMesh = true; break; case GL_POINTS: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_POLYGON: - default: - n = de->getNumIndices(); + n = 1; break; case GL_LINES: n = 2; @@ -1031,6 +994,12 @@ FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Ge case GL_QUADS: n = 4; break; + case GL_LINE_STRIP: + case GL_LINE_LOOP: + case GL_POLYGON: + default: + n = de->getNumIndices(); + break; } // Push and pop subfaces if polygon offset is on. @@ -1038,22 +1007,11 @@ FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Ge if (useMesh) { - writeMesh( geode, geom, mode ); - - writeMatrix( geode.getUserData() ); - writeComment( geode ); - writeMultitexture( geom ); - writeLocalVertexPool( geom, mode ); - - writePush(); - std::vector< unsigned int > indices; int idx; for (idx=0; idxindex( idx ) ); writeMeshPrimitive( indices, mode ); - - writePop(); } else {