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."
This commit is contained in:
Robert Osfield
2008-04-11 13:43:11 +00:00
parent 76e0198007
commit d0a2bf87f3
8 changed files with 267 additions and 105 deletions

View File

@@ -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 )
{

View File

@@ -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 );

View File

@@ -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 );
}
}

View File

@@ -18,7 +18,7 @@
#define __FLTEXP_MATERIAL_PALETTE_MANAGER_H__ 1
#include "ExportOptions.h"
#include <set>
#include <map>
namespace osg {
class Material;

View File

@@ -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<const osg::Vec3Array*>( v );
const osg::Vec4Array* c4 = dynamic_cast<const osg::Vec4Array*>( c );
const osg::Vec3Array* n3 = dynamic_cast<const osg::Vec3Array*>( n );
const osg::Vec2Array* t2 = dynamic_cast<const osg::Vec2Array*>( 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; idx<v->size(); 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<nToCopy; idx++ )
(*ret)[ idx ] = (*v2d)[ idx ]; // convert Vec2 double to Vec2 float
return ret.get();
}
default:
{
osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conv ersion to Vec2Array: " << arrayType << std::endl;
return NULL;
}
}
}
osg::ref_ptr< const osg::Vec3Array >
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<nToCopy; idx++ )
(*ret)[ idx ] = (*v3d)[ idx ]; // convert Vec3 double to Vec3 float
return ret.get();
}
default:
{
osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec3Array: " << arrayType << std::endl;
return NULL;
}
}
}
osg::ref_ptr< const osg::Vec3dArray >
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<nToCopy; idx++ )
(*ret)[ idx ] = (*v3f)[ idx ]; // convert Vec3 float to Vec3 double
return ret.get();
}
default:
{
osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec3dArray: " << arrayType << std::endl;
return NULL;
}
}
}
osg::ref_ptr< const osg::Vec4Array >
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<nToCopy; idx++ )
{
// convert Vec4 unsigned byte to Vec4 float
osg::Vec4& dest = (*ret)[ idx ];
osg::Vec4ub src = (*v4ub)[ idx ];
dest[0] = src[0] / 255.f;
dest[1] = src[1] / 255.f;
dest[2] = src[2] / 255.f;
dest[3] = src[3] / 255.f;
}
return ret.get();
}
default:
{
osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec4Array: " << arrayType << std::endl;
return NULL;
}
}
}

View File

@@ -47,7 +47,8 @@ public:
~VertexPaletteManager();
void add( const osg::Geometry& geom );
void add( const osg::Vec3Array* v, const osg::Vec4Array* c,
void 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=true );
@@ -55,6 +56,15 @@ public:
void write( DataOutputStream& dos ) const;
/*!
Static utility routines for handling the morass of array
types that could be found in a Geometry object's vertex/
normal/texcoord/color data. */
static osg::ref_ptr< const osg::Vec2Array > 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 );

View File

@@ -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<const osg::Vec3Array*>( 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<const osg::Vec2Array*>( geom.getTexCoordArray( unit ) );
const osg::Vec4Array* c4 = dynamic_cast<const osg::Vec4Array*>( c );
const osg::Vec3Array* n3 = dynamic_cast<const osg::Vec3Array*>( n );
const osg::Vec2Array* t2 = dynamic_cast<const osg::Vec2Array*>( 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; idx<numVerts; idx++ )
{
_records->writeFloat64( (*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<unsigned short>( -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

View File

@@ -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() );