From d0a2bf87f3d8af71ddd46590cf959dfeee05f863 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 11 Apr 2008 13:43:11 +0000 Subject: [PATCH] From Paul Martz,"Several misc changes, but the major fixes include: * Support for Vec4ubArray for color data * Support for material transparency Thanks to Neil Hughes, Jason Daly, yourself, and others for testing and reporting issues." --- .../OpenFlight/DataOutputStream.cpp | 9 - src/osgPlugins/OpenFlight/DataOutputStream.h | 1 - .../OpenFlight/MaterialPaletteManager.cpp | 15 +- .../OpenFlight/MaterialPaletteManager.h | 2 +- .../OpenFlight/VertexPaletteManager.cpp | 269 +++++++++++++++--- .../OpenFlight/VertexPaletteManager.h | 14 +- .../OpenFlight/expGeometryRecords.cpp | 58 ++-- .../OpenFlight/expPrimaryRecords.cpp | 4 +- 8 files changed, 267 insertions(+), 105 deletions(-) diff --git a/src/osgPlugins/OpenFlight/DataOutputStream.cpp b/src/osgPlugins/OpenFlight/DataOutputStream.cpp index d59759e0b..154f198cf 100644 --- a/src/osgPlugins/OpenFlight/DataOutputStream.cpp +++ b/src/osgPlugins/OpenFlight/DataOutputStream.cpp @@ -139,15 +139,6 @@ DataOutputStream::writeID( const std::string& val ) } -void -DataOutputStream::writeColor32( const osg::Vec4f& val ) -{ - writeUInt8( val.a() ); - writeUInt8( val.b() ); - writeUInt8( val.g() ); - writeUInt8( val.r() ); -} - void DataOutputStream::writeVec2f( const osg::Vec2f& val ) { diff --git a/src/osgPlugins/OpenFlight/DataOutputStream.h b/src/osgPlugins/OpenFlight/DataOutputStream.h index d9793cc24..cbb94e498 100644 --- a/src/osgPlugins/OpenFlight/DataOutputStream.h +++ b/src/osgPlugins/OpenFlight/DataOutputStream.h @@ -55,7 +55,6 @@ public: void writeString( const std::string& val, int size, char fill='\0' ); void writeID( const std::string& val ); - void writeColor32( const osg::Vec4f& val ); void writeVec2f( const osg::Vec2f& val ); void writeVec3f( const osg::Vec3f& val ); void writeVec4f( const osg::Vec4f& val ); diff --git a/src/osgPlugins/OpenFlight/MaterialPaletteManager.cpp b/src/osgPlugins/OpenFlight/MaterialPaletteManager.cpp index 56607a1d5..158b007a6 100644 --- a/src/osgPlugins/OpenFlight/MaterialPaletteManager.cpp +++ b/src/osgPlugins/OpenFlight/MaterialPaletteManager.cpp @@ -77,8 +77,7 @@ MaterialPaletteManager::write( DataOutputStream& dos ) const dos.writeInt16( (int16) MATERIAL_PALETTE_OP ); dos.writeInt16( 84 ); // Length - FIXME: hard-code/FLT version? dos.writeInt32( m.Index ); - std::string fakename = "SOMEFAKENAME"; - dos.writeString( fakename, 12 ); // Name - FIXME: put a 'real' name here? + dos.writeString( std::string( "" ), 12 ); // Name - FIXME: put a 'real' name here? dos.writeInt32( 0 ); // Flags dos.writeFloat32(ambient.r() ); dos.writeFloat32(ambient.g() ); @@ -93,7 +92,7 @@ MaterialPaletteManager::write( DataOutputStream& dos ) const dos.writeFloat32(emissive.g() ); dos.writeFloat32(emissive.b() ); dos.writeFloat32(shininess); - dos.writeFloat32(1.0f); // Alpha - unused + dos.writeFloat32( diffuse.a() ); // alpha dos.writeFloat32(1.0f); // 'Reserved' - unused if (m.Material->getAmbientFrontAndBack() == false || @@ -103,13 +102,9 @@ MaterialPaletteManager::write( DataOutputStream& dos ) const m.Material->getShininessFrontAndBack() == false ) { - std::stringstream ss; - ss << "Front and back faces of material \'" - << fakename - << "\' have different material" - << "properties - OpenFlt does not support this..." - << std::endl; - _fltOpt.getWriteResult().warn( ss.str() ); + std::string warning( "fltexp: No support for different front and back material properties." ); + osg::notify( osg::WARN ) << warning << std::endl; + _fltOpt.getWriteResult().warn( warning ); } } diff --git a/src/osgPlugins/OpenFlight/MaterialPaletteManager.h b/src/osgPlugins/OpenFlight/MaterialPaletteManager.h index 5d94584fc..aa0a4a3bb 100644 --- a/src/osgPlugins/OpenFlight/MaterialPaletteManager.h +++ b/src/osgPlugins/OpenFlight/MaterialPaletteManager.h @@ -18,7 +18,7 @@ #define __FLTEXP_MATERIAL_PALETTE_MANAGER_H__ 1 #include "ExportOptions.h" -#include +#include namespace osg { class Material; diff --git a/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp b/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp index bc151cfed..9104f03da 100644 --- a/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp +++ b/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp @@ -56,49 +56,36 @@ void VertexPaletteManager::add( const osg::Geometry& geom ) { const osg::Array* v = geom.getVertexArray(); + if (!v) + { + osg::notify( osg::WARN ) << "fltexp: Attempting to add NULL vertex array in VertexPaletteManager." << std::endl; + return; + } const osg::Array* c = geom.getColorArray(); const osg::Array* n = geom.getNormalArray(); const osg::Array* t = geom.getTexCoordArray( 0 ); - // TBD eventually need to be able to support other array types. - const osg::Vec3Array* v3 = dynamic_cast( v ); - const osg::Vec4Array* c4 = dynamic_cast( c ); - const osg::Vec3Array* n3 = dynamic_cast( n ); - const osg::Vec2Array* t2 = dynamic_cast( t ); + + const unsigned int size = v->getNumElements(); + osg::ref_ptr< const osg::Vec3dArray > v3 = asVec3dArray( v, size ); + osg::ref_ptr< const osg::Vec4Array > c4 = asVec4Array( c, size ); + osg::ref_ptr< const osg::Vec3Array > n3 = asVec3Array( n, size ); + osg::ref_ptr< const osg::Vec2Array > t2 = asVec2Array( t, size ); if (v && !v3) - { - std::string warning( "fltexp: VertexPalette: VertexArray is not Vec3Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt.getWriteResult().warn( warning ); return; - } if (c && !c4) - { - std::string warning( "fltexp: VertexPalette: ColorArray is not Vec4Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt.getWriteResult().warn( warning ); return; - } if (n && !n3) - { - std::string warning( "fltexp: VertexPalette: NormalArray is not Vec3Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt.getWriteResult().warn( warning ); return; - } if (t && !t2) - { - std::string warning( "fltexp: VertexPalette: TexCoordArray is not Vec2Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt.getWriteResult().warn( warning ); return; - } const bool cpv =( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX ); const bool npv =( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX ); - add( v3, c4, n3, t2, cpv, npv ); + add( v, v3.get(), c4.get(), n3.get(), t2.get(), cpv, npv ); } void -VertexPaletteManager::add( const osg::Vec3Array* v, const osg::Vec4Array* c, +VertexPaletteManager::add( const osg::Array* key, + const osg::Vec3dArray* v, const osg::Vec4Array* c, const osg::Vec3Array* n, const osg::Vec2Array* t, bool colorPerVertex, bool normalPerVertex, bool allowSharing ) { @@ -106,13 +93,15 @@ VertexPaletteManager::add( const osg::Vec3Array* v, const osg::Vec4Array* c, if (allowSharing) { - ArrayMap::iterator it = _arrayMap.find( v ); + ArrayMap::iterator it = _arrayMap.find( key ); if (it != _arrayMap.end()) needsInit = false; - _current = &( _arrayMap[ v ] ); + _current = &( _arrayMap[ key ] ); } else + { _current = &( _nonShared ); + } if (needsInit) { @@ -227,7 +216,7 @@ VertexPaletteManager::recordSize( PaletteRecordType recType ) } void -VertexPaletteManager::writeRecords( const osg::Vec3Array* v, const osg::Vec4Array* c, +VertexPaletteManager::writeRecords( const osg::Vec3dArray* v, const osg::Vec4Array* c, const osg::Vec3Array* n, const osg::Vec2Array* t, bool colorPerVertex, bool normalPerVertex ) { @@ -271,28 +260,24 @@ VertexPaletteManager::writeRecords( const osg::Vec3Array* v, const osg::Vec4Arra flags = PACKED_COLOR; - int cIdx( 0 ); - int nIdx( 0 ); size_t idx; for( idx=0; idxsize(); idx++) { uint32 packedColor( 0 ); - if (c) + if (c && colorPerVertex) { - osg::Vec4 color = (*c)[ cIdx ]; + osg::Vec4 color = (*c)[ idx ]; packedColor = (int)(color[3]*255) << 24 | (int)(color[2]*255) << 16 | (int)(color[1]*255) << 8 | (int)(color[0]*255); } - else - osg::notify( osg::DEBUG_INFO ) << "fltexp: VPM::writeRecords: no color array." << std::endl; // Write fields common to all record types. _vertices->writeInt16( opcode ); _vertices->writeUInt16( sizeBytes ); _vertices->writeUInt16( 0 ); // Color name _vertices->writeInt16( flags ); // Flags - _vertices->writeVec3d( osg::Vec3d( (*v)[ idx ] ) ); // Vertex + _vertices->writeVec3d( (*v)[ idx ] ); // Vertex // Now write record-specific field. switch( recType ) @@ -302,14 +287,14 @@ VertexPaletteManager::writeRecords( const osg::Vec3Array* v, const osg::Vec4Arra _vertices->writeUInt32( 0 ); // Vertex color index break; case VERTEX_CN: - _vertices->writeVec3f( (*n)[ nIdx ] ); // Normal + _vertices->writeVec3f( (*n)[ idx ] ); // Normal _vertices->writeInt32( packedColor ); // Packed color _vertices->writeUInt32( 0 ); // Vertex color index if (_fltOpt.getFlightFileVersionNumber() > ExportOptions::VERSION_15_7) _vertices->writeUInt32( 0 ); // Reserved break; case VERTEX_CNT: - _vertices->writeVec3f( (*n)[ nIdx ] ); // Normal + _vertices->writeVec3f( (*n)[ idx ] ); // Normal _vertices->writeVec2f( (*t)[ idx ] ); // Tex coord _vertices->writeInt32( packedColor ); // Packed color _vertices->writeUInt32( 0 ); // Vertex color index @@ -321,11 +306,209 @@ VertexPaletteManager::writeRecords( const osg::Vec3Array* v, const osg::Vec4Arra _vertices->writeUInt32( 0 ); // Vertex color index break; } + } +} - if (colorPerVertex) - cIdx++; - if (normalPerVertex) - nIdx++; + + +osg::ref_ptr< const osg::Vec2Array > +VertexPaletteManager::asVec2Array( const osg::Array* in, const unsigned int n ) +{ + if (!in) + return NULL; + + osg::Array::Type arrayType = in->getType(); + if (arrayType == osg::Array::Vec2ArrayType) + { + if (n <= in->getNumElements()) + { + osg::ref_ptr< const osg::Vec2Array > v2f = + dynamic_cast< const osg::Vec2Array* >( in ); + return v2f; + } + } + + const unsigned int nToCopy = ( (n < in->getNumElements()) ? n : in->getNumElements() ); + osg::ref_ptr< osg::Vec2Array > ret = new osg::Vec2Array( n ); + + switch( arrayType ) + { + case osg::Array::Vec2ArrayType: + { + // No need to convert data, but must copy into correctly-sized array. + // If the size was correct, we wouldn't be here. + osg::ref_ptr< const osg::Vec2Array > v2f = + dynamic_cast< const osg::Vec2Array* >( in ); + ret->assign( v2f->begin(), v2f->end() );; + ret->resize( n ); + return ret.get(); + } + case osg::Array::Vec2dArrayType: + { + osg::ref_ptr< const osg::Vec2dArray > v2d = + dynamic_cast< const osg::Vec2dArray* >( in ); + unsigned int idx; + for (idx=0; idx +VertexPaletteManager::asVec3Array( const osg::Array* in, const unsigned int n ) +{ + if (!in) + return NULL; + + osg::Array::Type arrayType = in->getType(); + if (arrayType == osg::Array::Vec3ArrayType) + { + if (n <= in->getNumElements()) + { + osg::ref_ptr< const osg::Vec3Array > v3f = + dynamic_cast< const osg::Vec3Array* >( in ); + return v3f; + } + } + + const unsigned int nToCopy = ( (n < in->getNumElements()) ? n : in->getNumElements() ); + osg::ref_ptr< osg::Vec3Array > ret = new osg::Vec3Array( n ); + + switch( arrayType ) + { + case osg::Array::Vec3ArrayType: + { + // No need to convert data, but must copy into correctly-sized array. + // If the size was correct, we wouldn't be here. + osg::ref_ptr< const osg::Vec3Array > v3f = + dynamic_cast< const osg::Vec3Array* >( in ); + ret->assign( v3f->begin(), v3f->end() );; + ret->resize( n ); + return ret.get(); + } + case osg::Array::Vec3dArrayType: + { + osg::ref_ptr< const osg::Vec3dArray > v3d = + dynamic_cast< const osg::Vec3dArray* >( in ); + unsigned int idx; + for (idx=0; idx +VertexPaletteManager::asVec3dArray( const osg::Array* in, const unsigned int n ) +{ + if (!in) + return NULL; + + osg::Array::Type arrayType = in->getType(); + if (arrayType == osg::Array::Vec3dArrayType) + { + if (n <= in->getNumElements()) + { + osg::ref_ptr< const osg::Vec3dArray > v3d = + dynamic_cast< const osg::Vec3dArray* >( in ); + return v3d; + } + } + + const unsigned int nToCopy = ( (n < in->getNumElements()) ? n : in->getNumElements() ); + osg::ref_ptr< osg::Vec3dArray > ret = new osg::Vec3dArray( n ); + + switch( arrayType ) + { + case osg::Array::Vec3dArrayType: + { + // No need to convert data, but must copy into correctly-sized array. + // If the size was correct, we wouldn't be here. + osg::ref_ptr< const osg::Vec3dArray > v3d = + dynamic_cast< const osg::Vec3dArray* >( in ); + ret->assign( v3d->begin(), v3d->end() );; + ret->resize( n ); + return ret.get(); + } + case osg::Array::Vec3ArrayType: + { + osg::ref_ptr< const osg::Vec3Array > v3f = + dynamic_cast< const osg::Vec3Array* >( in ); + unsigned int idx; + for (idx=0; idx +VertexPaletteManager::asVec4Array( const osg::Array* in, const unsigned int n ) +{ + if (!in) + return NULL; + + osg::Array::Type arrayType = in->getType(); + if (arrayType == osg::Array::Vec4ArrayType) + { + if (n <= in->getNumElements()) + { + osg::ref_ptr< const osg::Vec4Array > v4f = + dynamic_cast< const osg::Vec4Array* >( in ); + return v4f; + } + } + + const unsigned int nToCopy = ( (n < in->getNumElements()) ? n : in->getNumElements() ); + osg::ref_ptr< osg::Vec4Array > ret = new osg::Vec4Array( n ); + + switch( arrayType ) + { + case osg::Array::Vec4ArrayType: + { + // No need to convert data, but must copy into correctly-sized array. + // If the size was correct, we wouldn't be here. + osg::ref_ptr< const osg::Vec4Array > v4f = + dynamic_cast< const osg::Vec4Array* >( in ); + ret->assign( v4f->begin(), v4f->end() );; + ret->resize( n ); + return ret.get(); + } + case osg::Array::Vec4ubArrayType: + { + osg::ref_ptr< const osg::Vec4ubArray > v4ub = + dynamic_cast< const osg::Vec4ubArray* >( in ); + unsigned int idx; + for (idx=0; idx asVec2Array( const osg::Array* in, const unsigned int n ); + static osg::ref_ptr< const osg::Vec3Array > asVec3Array( const osg::Array* in, const unsigned int n ); + static osg::ref_ptr< const osg::Vec3dArray > asVec3dArray( const osg::Array* in, const unsigned int n ); + static osg::ref_ptr< const osg::Vec4Array > asVec4Array( const osg::Array* in, const unsigned int n ); + protected: typedef enum { VERTEX_C, @@ -67,7 +77,7 @@ protected: const osg::Array* n, const osg::Array* t ); unsigned int recordSize( PaletteRecordType recType ); - void writeRecords( const osg::Vec3Array* v, const osg::Vec4Array* c, + void writeRecords( const osg::Vec3dArray* v, const osg::Vec4Array* c, const osg::Vec3Array* n, const osg::Vec2Array* t, bool colorPerVertex, bool normalPerVertex ); diff --git a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp index cddd62805..438ad9a87 100644 --- a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp @@ -562,7 +562,7 @@ FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom, GLenum mode ) const osg::Array* v = geom.getVertexArray(); uint32 numVerts( v->getNumElements() ); - const osg::Vec3Array* v3 = dynamic_cast( v ); + osg::ref_ptr< const osg::Vec3dArray > v3 = VertexPaletteManager::asVec3dArray( v, numVerts ); if (!v3) { std::string warning( "fltexp: writeLocalVertexPool: VertexArray is not Vec3Array." ); @@ -576,51 +576,36 @@ FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom, GLenum mode ) const osg::Array* n = geom.getNormalArray(); const osg::Array* t = geom.getTexCoordArray( 0 ); - std::vector< const osg::Vec2Array* > mtc; + 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 ] = dynamic_cast( geom.getTexCoordArray( unit ) ); - - const osg::Vec4Array* c4 = dynamic_cast( c ); - const osg::Vec3Array* n3 = dynamic_cast( n ); - const osg::Vec2Array* t2 = dynamic_cast( t ); - if (c && !c4) - { - std::string warning( "fltexp: writeLocalVertexPool: ColorArray is not Vec4Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; - } - if (n && !n3) - { - std::string warning( "fltexp: writeLocalVertexPool: NormalArray is not Vec3Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; - } - if (t && !t2) - { - std::string warning( "fltexp: writeLocalVertexPool: TexCoordArray is not Vec2Array." ); - osg::notify( osg::WARN ) << warning << std::endl; - _fltOpt->getWriteResult().warn( warning ); - return; - } + mtc[ unit ] = VertexPaletteManager::asVec2Array( geom.getTexCoordArray( unit ), numVerts ); uint32 attr( HAS_POSITION ); unsigned int vertSize( sizeof( float64 ) * 3 ); - if (c4 && ( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) ) + if ( ( c4 != NULL ) && ( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) ) { attr |= HAS_RGBA_COLOR; vertSize += sizeof( unsigned int ); } - if (n3 && ( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) ) + if ( ( n3 != NULL ) && ( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) ) { attr |= HAS_NORMAL; vertSize += ( sizeof( float32 ) * 3 ); } - if (t2) + if ( t2 != NULL ) { attr |= HAS_BASE_UV; vertSize += ( sizeof( float32 ) * 2 ); @@ -676,9 +661,7 @@ FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom, GLenum mode ) unsigned int idx; for( idx=0; idxwriteFloat64( (*v3)[ idx ][0] ); - _records->writeFloat64( (*v3)[ idx ][1] ); - _records->writeFloat64( (*v3)[ idx ][2] ); + _records->writeVec3d( (*v3)[ idx ] ); if (attr & HAS_RGBA_COLOR) { @@ -763,10 +746,11 @@ FltExportVisitor::writeMultitexture( const osg::Geometry& geom ) _fltOpt->getWriteResult().warn( warning.str() ); } - _records->writeUInt16( textureIndex ); // texture index + // texture index (this value is an unsigned int, but has a -1 default per oflt spec: ugh) + _records->writeUInt16( static_cast< uint16 >( textureIndex ) ); _records->writeUInt16( 0 ); // TBD effect // mapping index (this value is an unsigned int, but has a -1 default per oflt spec: ugh) - _records->writeUInt16( static_cast( -1 ) ); + _records->writeUInt16( static_cast< uint16 >( -1 ) ); _records->writeUInt16( 0 ); // data } } @@ -894,7 +878,7 @@ FltExportVisitor::handleDrawArrays( const osg::DrawArrays* da, const osg::Geomet else { const unsigned int max( first+count ); - while (first+n <= max) + while ((unsigned int)( first+n ) <= max) { // Need: // * Geode for record name (but also need to handle diff --git a/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp b/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp index 4fddee939..64a1b2eb4 100644 --- a/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp @@ -743,7 +743,7 @@ FltExportVisitor::writeLightPoint( const osgSim::LightPointNode* lpn ) } { - osg::ref_ptr< osg::Vec3Array > v = new osg::Vec3Array( lpn->getNumLightPoints() ); + osg::ref_ptr< osg::Vec3dArray > v = new osg::Vec3dArray( lpn->getNumLightPoints() ); osg::ref_ptr< osg::Vec4Array > c = new osg::Vec4Array( lpn->getNumLightPoints() ); osg::ref_ptr< osg::Vec3Array > n = new osg::Vec3Array( lpn->getNumLightPoints() ); osg::Vec3f normal( 0.f, 0.f, 1.f ); @@ -760,7 +760,7 @@ FltExportVisitor::writeLightPoint( const osgSim::LightPointNode* lpn ) normal = ds->getDirection(); (*n)[ idx ] = normal; } - _vertexPalette->add( v.get(), c.get(), n.get(), NULL, true, true, false ); + _vertexPalette->add( (const osg::Array*)NULL, v.get(), c.get(), n.get(), NULL, true, true, false ); } writeMatrix( lpn->getUserData() );