From 85281a6d1bd69baca48b1b66838df8a5567227f1 Mon Sep 17 00:00:00 2001 From: Paul MARTZ Date: Thu, 5 May 2011 01:59:10 +0000 Subject: [PATCH] 2.8 branch: This is a wholesale update of all OpenFlight plugin source files from trunk. The 2.8.x FLT plugin is now in sync with trunk r12297 (April 19 2011). This commit includes the osgSim MultiSwitch changes in r11971. --- include/osgSim/MultiSwitch | 16 +- .../OpenFlight/AncillaryRecords.cpp | 30 +++- src/osgPlugins/OpenFlight/CMakeLists.txt | 3 - src/osgPlugins/OpenFlight/Document.cpp | 7 +- src/osgPlugins/OpenFlight/Document.h | 3 + src/osgPlugins/OpenFlight/ExportOptions.cpp | 22 +-- src/osgPlugins/OpenFlight/ExportOptions.h | 1 - .../OpenFlight/FltExportVisitor.cpp | 12 +- src/osgPlugins/OpenFlight/FltExportVisitor.h | 3 +- src/osgPlugins/OpenFlight/GeometryRecords.cpp | 140 +++++++++++++++++- .../OpenFlight/MaterialPaletteManager.cpp | 2 +- src/osgPlugins/OpenFlight/PaletteRecords.cpp | 21 ++- src/osgPlugins/OpenFlight/PrimaryRecords.cpp | 26 ++-- .../OpenFlight/ReaderWriterATTR.cpp | 2 +- src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp | 34 +++-- src/osgPlugins/OpenFlight/Record.h | 1 + .../OpenFlight/RecordInputStream.cpp | 4 +- src/osgPlugins/OpenFlight/Registry.cpp | 4 +- .../OpenFlight/VertexPaletteManager.cpp | 26 ++-- src/osgPlugins/OpenFlight/VertexRecords.cpp | 6 +- .../OpenFlight/expAncillaryRecords.cpp | 4 +- .../OpenFlight/expGeometryRecords.cpp | 110 ++++++++++---- .../OpenFlight/expPrimaryRecords.cpp | 3 +- src/osgSim/MultiSwitch.cpp | 8 + 24 files changed, 371 insertions(+), 117 deletions(-) diff --git a/include/osgSim/MultiSwitch b/include/osgSim/MultiSwitch index d400279b6..7501e5d75 100644 --- a/include/osgSim/MultiSwitch +++ b/include/osgSim/MultiSwitch @@ -69,8 +69,9 @@ class OSGSIM_EXPORT MultiSwitch : public osg::Group /** Get which of the available switch set lists to use.*/ unsigned int getActiveSwitchSet() const { return _activeSwitchSet; } - typedef std::vector ValueList; - typedef std::vector SwitchSetList; + typedef std::vector ValueList; + typedef std::vector SwitchSetList; + typedef std::vector SwitchSetNameList; /** Set the compile set of different values.*/ void setSwitchSetList(const SwitchSetList& switchSetList); @@ -84,6 +85,10 @@ class OSGSIM_EXPORT MultiSwitch : public osg::Group /** Get the a single set of different values for a particular switch set.*/ const ValueList& getValueList(unsigned int switchSet) const { return _values[switchSet]; } + void setValueName(unsigned int switchSet, const std::string& name); + + const std::string& getValueName(unsigned int switchSet) const { return _valueNames[switchSet]; } + protected : virtual ~MultiSwitch() {} @@ -91,9 +96,10 @@ class OSGSIM_EXPORT MultiSwitch : public osg::Group void expandToEncompassSwitchSet(unsigned int switchSet); // this is effectively a list of bit mask. - bool _newChildDefaultValue; - unsigned int _activeSwitchSet; - SwitchSetList _values; + bool _newChildDefaultValue; + unsigned int _activeSwitchSet; + SwitchSetList _values; + SwitchSetNameList _valueNames; }; } diff --git a/src/osgPlugins/OpenFlight/AncillaryRecords.cpp b/src/osgPlugins/OpenFlight/AncillaryRecords.cpp index a5e7ffdef..fce52d9c6 100644 --- a/src/osgPlugins/OpenFlight/AncillaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/AncillaryRecords.cpp @@ -316,6 +316,35 @@ class Replicate : public Record REGISTER_FLTRECORD(Replicate, REPLICATE_OP) + +/** IndexedString - + */ +class IndexedString : public Record +{ + public: + + IndexedString() {} + + META_Record(IndexedString) + + protected: + + virtual ~IndexedString() {} + + virtual void readRecord(RecordInputStream& in, Document& /*document*/) + { + std::streamsize size = in.getRecordSize(); + uint32 index = in.readUInt32(); + std::string name = in.readString(size-8); + + if (_parent.valid()) + _parent->setMultiSwitchValueName(index, name); + } +}; + +REGISTER_FLTRECORD(IndexedString, INDEXED_STRING_OP) + + // Prevent "unknown record" message for the following ancillary records: REGISTER_FLTRECORD(DummyRecord, OLD_TRANSLATE2_OP) REGISTER_FLTRECORD(DummyRecord, OLD_ROTATE_ABOUT_POINT_OP) @@ -327,7 +356,6 @@ REGISTER_FLTRECORD(DummyRecord, OLD_ROTATE_ABOUT_POINT2_OP) REGISTER_FLTRECORD(DummyRecord, OLD_ROTATE_SCALE_TO_POINT_OP) REGISTER_FLTRECORD(DummyRecord, OLD_PUT_TRANSFORM_OP) REGISTER_FLTRECORD(DummyRecord, OLD_BOUNDING_BOX_OP) -REGISTER_FLTRECORD(DummyRecord, INDEXED_STRING_OP) REGISTER_FLTRECORD(DummyRecord, ROAD_ZONE_OP) REGISTER_FLTRECORD(DummyRecord, ROTATE_ABOUT_EDGE_OP) REGISTER_FLTRECORD(DummyRecord, TRANSLATE_OP) diff --git a/src/osgPlugins/OpenFlight/CMakeLists.txt b/src/osgPlugins/OpenFlight/CMakeLists.txt index c29293fce..f446368a9 100644 --- a/src/osgPlugins/OpenFlight/CMakeLists.txt +++ b/src/osgPlugins/OpenFlight/CMakeLists.txt @@ -1,6 +1,3 @@ -#this file is automatically generated - - SET(TARGET_SRC AncillaryRecords.cpp AttrData.cpp diff --git a/src/osgPlugins/OpenFlight/Document.cpp b/src/osgPlugins/OpenFlight/Document.cpp index dc02d9095..d6fee5df6 100644 --- a/src/osgPlugins/OpenFlight/Document.cpp +++ b/src/osgPlugins/OpenFlight/Document.cpp @@ -26,6 +26,7 @@ Document::Document() : _replaceClampWithClampToEdge(false), _preserveFace(false), _preserveObject(false), + _replaceDoubleSidedPolys(false), _defaultDOFAnimationState(false), _useTextureAlphaForTransparancyBinning(true), _useBillboardCenter(false), @@ -83,7 +84,7 @@ void Document::pushExtension() { if (!_currentPrimaryRecord.valid()) { - osg::notify(osg::WARN) << "No current primary in Document::pushExtension()." << std::endl; + OSG_WARN << "No current primary in Document::pushExtension()." << std::endl; return; } @@ -95,7 +96,7 @@ void Document::popExtension() _currentPrimaryRecord=_extensionStack.back().get(); if (!_currentPrimaryRecord.valid()) { - osg::notify(osg::WARN) << "Can't decide primary in Document::popExtension()." << std::endl; + OSG_WARN << "Can't decide primary in Document::popExtension()." << std::endl; return; } @@ -118,7 +119,7 @@ void Document::setSubSurfacePolygonOffset(int level, osg::PolygonOffset* po) osg::PolygonOffset* Document::getSubSurfacePolygonOffset(int level) { - osg::notify(osg::DEBUG_INFO)<<"Document::getSubSurfacePolygonOffset("<& po = _subsurfacePolygonOffsets[level]; if (!po) { diff --git a/src/osgPlugins/OpenFlight/Document.h b/src/osgPlugins/OpenFlight/Document.h index 60c963b2d..ac9f08adc 100644 --- a/src/osgPlugins/OpenFlight/Document.h +++ b/src/osgPlugins/OpenFlight/Document.h @@ -182,6 +182,8 @@ class Document bool getPreserveFace() const { return _preserveFace; } void setPreserveObject(bool flag) { _preserveObject = flag; } bool getPreserveObject() const { return _preserveObject; } + void setReplaceDoubleSidedPolys(bool flag) { _replaceDoubleSidedPolys = flag; } + bool getReplaceDoubleSidedPolys() const { return _replaceDoubleSidedPolys; } void setDefaultDOFAnimationState(bool state) { _defaultDOFAnimationState = state; } bool getDefaultDOFAnimationState() const { return _defaultDOFAnimationState; } void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; } @@ -206,6 +208,7 @@ class Document bool _replaceClampWithClampToEdge; bool _preserveFace; bool _preserveObject; + bool _replaceDoubleSidedPolys; bool _defaultDOFAnimationState; bool _useTextureAlphaForTransparancyBinning; bool _useBillboardCenter; diff --git a/src/osgPlugins/OpenFlight/ExportOptions.cpp b/src/osgPlugins/OpenFlight/ExportOptions.cpp index 80c278c5c..6adeb75e2 100644 --- a/src/osgPlugins/OpenFlight/ExportOptions.cpp +++ b/src/osgPlugins/OpenFlight/ExportOptions.cpp @@ -153,20 +153,20 @@ ExportOptions::parseOptionsString() // See if it's a Boolen/toggle if ( token == _validateOption ) { - osg::notify( osg::INFO ) << "fltexp: Found: " << token << std::endl; + OSG_INFO << "fltexp: Found: " << token << std::endl; setValidateOnly( true ); continue; } if ( token == _stripTextureFilePathOption ) { - osg::notify( osg::INFO ) << "fltexp: Found: " << token << std::endl; + OSG_INFO << "fltexp: Found: " << token << std::endl; setStripTextureFilePath( true ); continue; } // Protect against unrecognized options without values if ( pos == str.npos ) { - osg::notify( osg::WARN ) << "fltexp: Bogus OptionString: " << token << std::endl; + OSG_WARN << "fltexp: Bogus OptionString: " << token << std::endl; continue; } @@ -187,19 +187,19 @@ ExportOptions::parseOptionsString() if (token == _versionOption) { - osg::notify( osg::INFO ) << "fltexp: Token: " << token << ", Value: " << value << std::endl; + OSG_INFO << "fltexp: Token: " << token << ", Value: " << value << std::endl; int version( VERSION_16_1 ); if( value == std::string( "15.7" ) ) version = VERSION_15_7; else if( value == std::string( "15.8" ) ) version = VERSION_15_8; else if( value != std::string( "16.1" ) ) - osg::notify( osg::WARN ) << "fltexp: Unsupported version: " << value << ". Defaulting to 16.1." << std::endl; + OSG_WARN << "fltexp: Unsupported version: " << value << ". Defaulting to 16.1." << std::endl; setFlightFileVersionNumber( version ); } else if (token == _unitsOption) { - osg::notify( osg::INFO ) << "fltexp: Token: " << token << ", Value: " << value << std::endl; + OSG_INFO << "fltexp: Token: " << token << ", Value: " << value << std::endl; FlightUnits units( METERS ); if( value == std::string( "KILOMETERS" ) ) units = KILOMETERS; @@ -210,26 +210,26 @@ ExportOptions::parseOptionsString() else if( value == std::string( "NAUTICAL_MILES" ) ) units = NAUTICAL_MILES; else if( value != std::string( "METERS" ) ) - osg::notify( osg::WARN ) << "fltexp: Unsupported units: " << value << ". Defaulting to METERS." << std::endl; + OSG_WARN << "fltexp: Unsupported units: " << value << ". Defaulting to METERS." << std::endl; setFlightUnits( units ); } else if (token == _tempDirOption) { - osg::notify( osg::INFO ) << "fltexp: Token: " << token << ", Value: " << value << std::endl; + OSG_INFO << "fltexp: Token: " << token << ", Value: " << value << std::endl; setTempDir( value ); } else if (token == _lightingOption) { - osg::notify( osg::INFO ) << "fltexp: Token: " << token << ", Value: " << value << std::endl; + OSG_INFO << "fltexp: Token: " << token << ", Value: " << value << std::endl; bool lighting( true ); if (value == std::string( "OFF" ) ) lighting = false; else if (value != std::string( "ON" ) ) - osg::notify( osg::WARN ) << "fltexp: Unsupported lighting value: " << value << ". Defaulting to ON." << std::endl; + OSG_WARN << "fltexp: Unsupported lighting value: " << value << ". Defaulting to ON." << std::endl; setLightingDefault( lighting ); } else - osg::notify( osg::WARN ) << "fltexp: Bogus OptionString: " << token << std::endl; + OSG_WARN << "fltexp: Bogus OptionString: " << token << std::endl; } } diff --git a/src/osgPlugins/OpenFlight/ExportOptions.h b/src/osgPlugins/OpenFlight/ExportOptions.h index b1907bef3..99b5b54a2 100644 --- a/src/osgPlugins/OpenFlight/ExportOptions.h +++ b/src/osgPlugins/OpenFlight/ExportOptions.h @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/src/osgPlugins/OpenFlight/FltExportVisitor.cpp b/src/osgPlugins/OpenFlight/FltExportVisitor.cpp index 47e0db85c..a2fcf1719 100644 --- a/src/osgPlugins/OpenFlight/FltExportVisitor.cpp +++ b/src/osgPlugins/OpenFlight/FltExportVisitor.cpp @@ -117,12 +117,12 @@ FltExportVisitor::~FltExportVisitor() // Delete our temp file. if (_recordsStr.is_open()) { - osg::notify( osg::WARN ) << "fltexp: FltExportVisitor destructor has an open temp file." << std::endl; + OSG_WARN << "fltexp: FltExportVisitor destructor has an open temp file." << std::endl; // This should not happen. FltExportVisitor::complete should close // this file before we get to this destructor. return; } - osg::notify( osg::INFO ) << "fltexp: Deleting temp file " << _recordsTempName << std::endl; + OSG_INFO << "fltexp: Deleting temp file " << _recordsTempName << std::endl; FLTEXP_DELETEFILE( _recordsTempName.c_str() ); } @@ -356,7 +356,7 @@ FltExportVisitor::apply( osg::Geode& node ) if (!geom) { std::string warning( "fltexp: Non-Geometry Drawable encountered. Ignoring." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); continue; } @@ -391,7 +391,7 @@ FltExportVisitor::apply( osg::Geode& node ) else { std::string warning( "fltexp: Unknown PrimitiveSet type." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } @@ -429,7 +429,7 @@ FltExportVisitor::apply( osg::Geode& node ) else { std::string warning( "fltexp: Unknown PrimitiveSet type." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } @@ -461,7 +461,7 @@ FltExportVisitor::apply( osg::Node& node ) // would export a Group record then continue traversal. Because we are // a Node, there's no way to continue traversal, so just return.) std::string warning( "fltexp: Unknown Node in OpenFlight export." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } diff --git a/src/osgPlugins/OpenFlight/FltExportVisitor.h b/src/osgPlugins/OpenFlight/FltExportVisitor.h index 21d2e4161..0a89aa978 100644 --- a/src/osgPlugins/OpenFlight/FltExportVisitor.h +++ b/src/osgPlugins/OpenFlight/FltExportVisitor.h @@ -136,7 +136,8 @@ public: void writeMeshPrimitive( const std::vector& indices, GLenum mode ); void writeLocalVertexPool( const osg::Geometry& geom ); void writeMultitexture( const osg::Geometry& geom ); - void writeUVList( int numVerts, const osg::Geometry& geom ); + void writeUVList( int numVerts, const osg::Geometry& geom, const std::vector& indices ); + void writeUVList( int numVerts, const osg::Geometry& geom, unsigned int first=0); // Light Point records void writeLightPoint(); diff --git a/src/osgPlugins/OpenFlight/GeometryRecords.cpp b/src/osgPlugins/OpenFlight/GeometryRecords.cpp index fddfd69e1..a943185c7 100644 --- a/src/osgPlugins/OpenFlight/GeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/GeometryRecords.cpp @@ -29,8 +29,108 @@ #include "Document.h" #include "RecordInputStream.h" +#include + namespace flt { +template +void reverseWindingOrder( ARRAY* data, GLenum mode, GLint first, GLint last ) +{ + switch( mode ) + { + case osg::PrimitiveSet::TRIANGLES: + case osg::PrimitiveSet::QUADS: + case osg::PrimitiveSet::POLYGON: + // reverse all the vertices. + std::reverse(data->begin()+first, data->begin()+last); + break; + case osg::PrimitiveSet::TRIANGLE_STRIP: + case osg::PrimitiveSet::QUAD_STRIP: + // reverse only the shared edges. + for( GLint i = first; i < last-1; i+=2 ) + { + std::swap( (*data)[i], (*data)[i+1] ); + } + break; + case osg::PrimitiveSet::TRIANGLE_FAN: + // reverse all vertices except the first vertex. + std::reverse(data->begin()+first+1, data->begin()+last); + break; + } +} + +void addDrawableAndReverseWindingOrder( osg::Geode* geode ) +{ + // Replace double sided polygons by duplicating the drawables and inverting the normals. + std::vector new_drawables; + + for (size_t i=0; igetNumDrawables(); ++i) + { + const osg::Geometry* geometry = dynamic_cast(geode->getDrawable(i)); + if(geometry) + { + osg::Geometry* geom = new osg::Geometry(*geometry + , osg::CopyOp::DEEP_COPY_ARRAYS | osg::CopyOp::DEEP_COPY_PRIMITIVES); + new_drawables.push_back(geom); + + for( size_t i = 0; i < geom->getNumPrimitiveSets( ); ++i ) + { + osg::DrawArrays* drawarray = dynamic_cast( geom->getPrimitiveSet( i ) ); + if( drawarray ) + { + GLint first = drawarray->getFirst(); + GLint last = drawarray->getFirst()+drawarray->getCount(); + + // Invert vertex order. + osg::Vec3Array* vertices = dynamic_cast(geom->getVertexArray()); + if( vertices ) + { + reverseWindingOrder( vertices, drawarray->getMode(), first, last ); + } + + if( geom->getNormalBinding( ) == osg::Geometry::BIND_PER_VERTEX ) + { + osg::Vec3Array* normals = dynamic_cast(geom->getNormalArray()); + if( normals ) + { + // First, invert the direction of the normals. + for( GLint i = first; i < last; ++i ) + { + (*normals)[i] = -(*normals)[i]; + } + reverseWindingOrder( normals, drawarray->getMode(), first, last ); + } + } + + if( geom->getColorBinding( ) == osg::Geometry::BIND_PER_VERTEX ) + { + osg::Vec4Array* colors = dynamic_cast(geom->getColorArray()); + if( colors ) + { + reverseWindingOrder( colors, drawarray->getMode(), first, last ); + } + } + + for( size_t i = 0; i < geom->getNumTexCoordArrays(); ++i ) + { + osg::Vec2Array* UVs = dynamic_cast(geom->getTexCoordArray(i)); + if( UVs ) + { + reverseWindingOrder( UVs, drawarray->getMode(), first, last ); + } + } + } + } + } + } + + // Now add the new geometry drawable. + for( size_t i = 0; i < new_drawables.size( ); ++i ) + { + geode->addDrawable( new_drawables[i] ); + } +} + /* Face record */ class Face : public PrimaryRecord @@ -374,7 +474,15 @@ protected: break; } case SOLID_NO_BACKFACE: // Disable backface culling - stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); + if( document.getReplaceDoubleSidedPolys( ) ) + { + static osg::ref_ptr cullFace = new osg::CullFace(osg::CullFace::BACK); + stateset->setAttributeAndModes(cullFace.get(), osg::StateAttribute::ON); + } + else + { + stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); + } break; } @@ -477,6 +585,11 @@ protected: } } + if( getDrawMode( ) == SOLID_NO_BACKFACE && document.getReplaceDoubleSidedPolys( ) ) + { + addDrawableAndReverseWindingOrder( _geode.get() ); + } + osg::StateSet* stateset = _geode->getOrCreateStateSet(); // Translucent image? @@ -930,7 +1043,15 @@ protected: break; } case SOLID_NO_BACKFACE: // Disable backface culling - stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); + if( document.getReplaceDoubleSidedPolys( ) ) + { + static osg::ref_ptr cullFace = new osg::CullFace(osg::CullFace::BACK); + stateset->setAttributeAndModes(cullFace.get(), osg::StateAttribute::ON); + } + else + { + stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); + } break; } @@ -960,6 +1081,11 @@ protected: insertMatrixTransform(*_geode,*_matrix,_numberOfReplications); } + if( getDrawMode( ) == SOLID_NO_BACKFACE && document.getReplaceDoubleSidedPolys( ) ) + { + addDrawableAndReverseWindingOrder( _geode.get() ); + } + osg::StateSet* stateset = _geode->getOrCreateStateSet(); // Translucent image? @@ -1072,7 +1198,7 @@ protected: if (!coord.valid()) { - osg::notify(osg::NOTICE)<<"Warning: data error detected in LocalVertexPool::readRecord coord="<set( originLat, originLong ); _header->setUserData( loc ); - osg::notify(osg::INFO) << "DB lat=" << originLat << " lon=" << originLong << std::endl; + OSG_INFO << "DB lat=" << originLat << " lon=" << originLong << std::endl; document.setHeaderNode(_header.get()); } @@ -200,7 +200,7 @@ protected: void readRecord(RecordInputStream& in, Document& document) { std::string id = in.readString(8); - osg::notify(osg::DEBUG_INFO) << "ID: " << id << std::endl; + OSG_DEBUG << "ID: " << id << std::endl; /*int16 relativePriority =*/ in.readInt16(); in.forward(2); @@ -396,10 +396,10 @@ protected: if ((length_x*length_y*length_z)==0.0f) { - osg::notify(osg::NOTICE)<<"Warning: OpenFlight DegreeOfFreedom::readRecord() found erroneous axis definition:"<", "Export option: Specifies the version of the output OpenFlight file. Supported values include 15.7, 15.8, and 16.1. Default is 16.1. Example: \"version=15.8\"." ); - supportsOption( "units=", "Export option: Specifies the contents of the Units field of the OpenFliht header record. Valid values include INCHES, FEET, METERS, KILOMETERS, and NATICAL_MILES. Default is METERS. Example: \"units=METERS\"." ); + supportsOption( "units=", "Export option: Specifies the contents of the Units field of the OpenFlight header record. Valid values include INCHES, FEET, METERS, KILOMETERS, and NAUTICAL_MILES. Default is METERS. Example: \"units=METERS\"." ); supportsOption( "validate", "Export option: If present in the Options string, the plugin does not write an OpenFlight file. Instead, it returns an indication of the scene graph's suitability for OpenFlight export." ); supportsOption( "tempDir=", "Export option: Specifies the directory to use for creation of temporary files. If not specified, the directory is taken from the file name. If the file doesn't contain a path, the current working directory is used. Applications should set this to the name of their app-specific temp directory. If the path contains spaces, use double quotes to ensure correct parsing. Examples: \"tempDir=/tmp\", \"tempDir=\"C:\\My Temp Dir\"." ); supportsOption( "lighting=", "Export option: Specifies a default enable/disable state for lighting, for Nodes in the exported scene graph that don't set it explicitly. By default, the exporter assumes lighting is enabled (GL_LIGHTING ON). Set this to either ON or OFF. Example: \"lighting=OFF\"." ); @@ -310,7 +311,7 @@ class FLTReaderWriter : public ReaderWriter if ( !keepExternalReferences ) { - osg::notify(osg::DEBUG_INFO) << "keepExternalReferences not found, so externals will be re-readed"<getOptionString().find("clampToEdge")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "clampToEdge=" << document.getReplaceClampWithClampToEdge() << std::endl; + OSG_DEBUG << readerMsg << "clampToEdge=" << document.getReplaceClampWithClampToEdge() << std::endl; document.setKeepExternalReferences((options->getOptionString().find("keepExternalReferences")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "keepExternalReferences=" << document.getKeepExternalReferences() << std::endl; + OSG_DEBUG << readerMsg << "keepExternalReferences=" << document.getKeepExternalReferences() << std::endl; document.setPreserveFace((options->getOptionString().find("preserveFace")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "preserveFace=" << document.getPreserveFace() << std::endl; + OSG_DEBUG << readerMsg << "preserveFace=" << document.getPreserveFace() << std::endl; document.setPreserveObject((options->getOptionString().find("preserveObject")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "preserveObject=" << document.getPreserveObject() << std::endl; + OSG_DEBUG << readerMsg << "preserveObject=" << document.getPreserveObject() << std::endl; + + document.setReplaceDoubleSidedPolys((options->getOptionString().find("replaceDoubleSidedPolys")!=std::string::npos)); + OSG_DEBUG << readerMsg << "replaceDoubleSidedPolys=" << document.getReplaceDoubleSidedPolys() << std::endl; document.setDefaultDOFAnimationState((options->getOptionString().find("dofAnimation")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "dofAnimation=" << document.getDefaultDOFAnimationState() << std::endl; + OSG_DEBUG << readerMsg << "dofAnimation=" << document.getDefaultDOFAnimationState() << std::endl; document.setUseBillboardCenter((options->getOptionString().find("billboardCenter")!=std::string::npos)); - osg::notify(osg::DEBUG_INFO) << readerMsg << "billboardCenter=" << document.getUseBillboardCenter() << std::endl; + OSG_DEBUG << readerMsg << "billboardCenter=" << document.getUseBillboardCenter() << std::endl; document.setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")==std::string::npos); - osg::notify(osg::DEBUG_INFO) << readerMsg << "noTextureAlphaForTransparancyBinning=" << !document.getUseTextureAlphaForTransparancyBinning() << std::endl; + OSG_DEBUG << readerMsg << "noTextureAlphaForTransparancyBinning=" << !document.getUseTextureAlphaForTransparancyBinning() << std::endl; document.setReadObjectRecordData(options->getOptionString().find("readObjectRecordData")==std::string::npos); - osg::notify(osg::DEBUG_INFO) << readerMsg << "readObjectRecordData=" << !document.getReadObjectRecordData() << std::endl; + OSG_DEBUG << readerMsg << "readObjectRecordData=" << !document.getReadObjectRecordData() << std::endl; document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified. - osg::notify(osg::DEBUG_INFO) << readerMsg << "noUnitsConversion=" << !document.getDoUnitsConversion() << std::endl; + OSG_DEBUG << readerMsg << "noUnitsConversion=" << !document.getDoUnitsConversion() << std::endl; if (document.getDoUnitsConversion()) { @@ -533,9 +537,9 @@ class FLTReaderWriter : public ReaderWriter { if ( fileName.empty() ) { - osg::notify( osg::FATAL ) << "fltexp: writeNode: empty file name" << std::endl; return WriteResult::FILE_NOT_HANDLED; } + std::string ext = osgDB::getLowerCaseFileExtension( fileName ); if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED; @@ -549,7 +553,7 @@ class FLTReaderWriter : public ReaderWriter fOut.open( fileName.c_str(), std::ios::out | std::ios::binary ); if ( fOut.fail()) { - osg::notify( osg::FATAL ) << "fltexp: Failed to open output stream." << std::endl; + OSG_FATAL << "fltexp: Failed to open output stream." << std::endl; return WriteResult::ERROR_IN_WRITING_FILE; } @@ -583,7 +587,7 @@ class FLTReaderWriter : public ReaderWriter // If the temp directory doesn't already exist, make it. if ( !osgDB::makeDirectory( fltOpt->getTempDir() ) ) { - osg::notify( osg::FATAL ) << "fltexp: Error creating temp dir: " << fltOpt->getTempDir() << std::endl; + OSG_FATAL << "fltexp: Error creating temp dir: " << fltOpt->getTempDir() << std::endl; return WriteResult::ERROR_IN_WRITING_FILE; } } diff --git a/src/osgPlugins/OpenFlight/Record.h b/src/osgPlugins/OpenFlight/Record.h index 52cea77ac..64a835724 100644 --- a/src/osgPlugins/OpenFlight/Record.h +++ b/src/osgPlugins/OpenFlight/Record.h @@ -86,6 +86,7 @@ public: virtual void addVertex(Vertex& /*vertex*/) {} virtual void addVertexUV(int /*layer*/,const osg::Vec2& /*uv*/) {} virtual void addMorphVertex(Vertex& /*vertex0*/, Vertex& /*vertex100*/) {} + virtual void setMultiSwitchValueName(unsigned int /*switchSet*/, const std::string& /*name*/) {} void setNumberOfReplications(int num) { _numberOfReplications = num; } void setMatrix(const osg::Matrix& matrix) { _matrix = new osg::RefMatrix(matrix); } diff --git a/src/osgPlugins/OpenFlight/RecordInputStream.cpp b/src/osgPlugins/OpenFlight/RecordInputStream.cpp index 743dc7596..a5d904f17 100644 --- a/src/osgPlugins/OpenFlight/RecordInputStream.cpp +++ b/src/osgPlugins/OpenFlight/RecordInputStream.cpp @@ -47,7 +47,7 @@ bool RecordInputStream::readRecordBody(opcode_type opcode, size_type size, Docum const uint16 LITTLE_ENDIAN_POP_LEVEL_OP = 0x0B00; if (opcode==LITTLE_ENDIAN_POP_LEVEL_OP) { - osg::notify(osg::INFO) << "Little endian pop-level record" << std::endl; + OSG_INFO << "Little endian pop-level record" << std::endl; opcode=POP_LEVEL_OP; size=4; } @@ -76,7 +76,7 @@ bool RecordInputStream::readRecordBody(opcode_type opcode, size_type size, Docum } else // prototype not found { - osg::notify(osg::WARN) << "Unknown record, opcode=" << opcode << " size=" << size << std::endl; + OSG_WARN << "Unknown record, opcode=" << opcode << " size=" << size << std::endl; // Add to registry so we only have to see this error message once. Registry::instance()->addPrototype(opcode,new DummyRecord); diff --git a/src/osgPlugins/OpenFlight/Registry.cpp b/src/osgPlugins/OpenFlight/Registry.cpp index 3dd29f637..13bc72682 100644 --- a/src/osgPlugins/OpenFlight/Registry.cpp +++ b/src/osgPlugins/OpenFlight/Registry.cpp @@ -40,12 +40,12 @@ void Registry::addPrototype(int opcode, Record* prototype) { if (prototype==0L) { - osg::notify(osg::WARN) << "Not a record." << std::endl; + OSG_WARN << "Not a record." << std::endl; return; } if (_recordProtoMap.find(opcode) != _recordProtoMap.end()) - osg::notify(osg::WARN) << "Registry already contains prototype for opcode " << opcode << "." << std::endl; + OSG_WARN << "Registry already contains prototype for opcode " << opcode << "." << std::endl; _recordProtoMap[opcode] = prototype; } diff --git a/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp b/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp index 80593b7bb..ae6b8b47d 100644 --- a/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp +++ b/src/osgPlugins/OpenFlight/VertexPaletteManager.cpp @@ -42,12 +42,12 @@ VertexPaletteManager::~VertexPaletteManager() // Delete our temp file. if (_verticesStr.is_open()) { - osg::notify( osg::WARN ) << "fltexp: VertexPaletteManager destructor has an open temp file." << std::endl; + OSG_WARN << "fltexp: VertexPaletteManager destructor has an open temp file." << std::endl; // This should not happen. FltExportVisitor::complete should close // this file before we get to this destructor. return; } - osg::notify( osg::INFO ) << "fltexp: Deleting temp file " << _verticesTempName << std::endl; + OSG_INFO << "fltexp: Deleting temp file " << _verticesTempName << std::endl; FLTEXP_DELETEFILE( _verticesTempName.c_str() ); } } @@ -58,7 +58,7 @@ 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; + OSG_WARN << "fltexp: Attempting to add NULL vertex array in VertexPaletteManager." << std::endl; return; } const osg::Array* c = geom.getColorArray(); @@ -129,12 +129,12 @@ VertexPaletteManager::byteOffset( unsigned int idx ) const { if (!_current) { - osg::notify( osg::WARN ) << "fltexp: No current vertex array in VertexPaletteManager." << std::endl; + OSG_WARN << "fltexp: No current vertex array in VertexPaletteManager." << std::endl; return 4; } if (idx >= _current->_idxCount) { - osg::notify( osg::WARN ) << "fltexp: Index out of range in VertexPaletteManager." << std::endl; + OSG_WARN << "fltexp: Index out of range in VertexPaletteManager." << std::endl; return 4; } @@ -232,19 +232,19 @@ VertexPaletteManager::writeRecords( const osg::Vec3dArray* v, const osg::Vec4Arr case VERTEX_CN: opcode = VERTEX_CN_OP; if (!n) - osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no normal array." << std::endl; + OSG_WARN << "fltexp: VPM::writeRecords: no normal array." << std::endl; break; case VERTEX_CNT: opcode = VERTEX_CNT_OP; if (!n) - osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no normal array." << std::endl; + OSG_WARN << "fltexp: VPM::writeRecords: no normal array." << std::endl; if (!t) - osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; + OSG_WARN << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; break; case VERTEX_CT: opcode = VERTEX_CT_OP; if (!t) - osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; + OSG_WARN << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; break; } @@ -368,7 +368,7 @@ VertexPaletteManager::asVec2Array( const osg::Array* in, const unsigned int n ) } default: { - osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec2Array: " << arrayType << std::endl; + OSG_WARN << "fltexp: Unsupported array type in conversion to Vec2Array: " << arrayType << std::endl; return NULL; } } @@ -416,7 +416,7 @@ VertexPaletteManager::asVec3Array( const osg::Array* in, const unsigned int n ) } default: { - osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec3Array: " << arrayType << std::endl; + OSG_WARN << "fltexp: Unsupported array type in conversion to Vec3Array: " << arrayType << std::endl; return NULL; } } @@ -464,7 +464,7 @@ VertexPaletteManager::asVec3dArray( const osg::Array* in, const unsigned int n ) } default: { - osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec3dArray: " << arrayType << std::endl; + OSG_WARN << "fltexp: Unsupported array type in conversion to Vec3dArray: " << arrayType << std::endl; return NULL; } } @@ -520,7 +520,7 @@ VertexPaletteManager::asVec4Array( const osg::Array* in, const unsigned int n ) } default: { - osg::notify( osg::WARN ) << "fltexp: Unsupported array type in conversion to Vec4Array: " << arrayType << std::endl; + OSG_WARN << "fltexp: Unsupported array type in conversion to Vec4Array: " << arrayType << std::endl; return NULL; } } diff --git a/src/osgPlugins/OpenFlight/VertexRecords.cpp b/src/osgPlugins/OpenFlight/VertexRecords.cpp index 30c5cbb8f..a6de5eeff 100644 --- a/src/osgPlugins/OpenFlight/VertexRecords.cpp +++ b/src/osgPlugins/OpenFlight/VertexRecords.cpp @@ -190,17 +190,17 @@ class VertexCNT : public Record if (!coord.valid()) { - osg::notify(osg::NOTICE)<<"Warning: data error detected in VertexCNT::readRecord coord="<getWriteResult().warn( warning ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; continue; } uint16 length( (uint16)iLen ); @@ -100,7 +100,7 @@ FltExportVisitor::writeMatrix( const osg::Referenced* ref ) void FltExportVisitor::writeContinuationRecord( const unsigned short length ) { - osg::notify( osg::DEBUG_INFO ) << "fltexp: Continuation record length: " << length+4 << std::endl; + OSG_DEBUG << "fltexp: Continuation record length: " << length+4 << std::endl; _records->writeInt16( (int16) CONTINUATION_OP ); _records->writeUInt16( length+4 ); } diff --git a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp index 2544a15b6..9eb500e31 100644 --- a/src/osgPlugins/OpenFlight/expGeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/expGeometryRecords.cpp @@ -185,7 +185,7 @@ FltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, case GL_POINTS: { std::string warning( "fltexp: GL_POINTS not supported in FLT export." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; break; @@ -195,7 +195,7 @@ FltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, case GL_QUAD_STRIP: { std::string warning( "fltexp: Wrong mode in Face record." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; break; @@ -248,7 +248,7 @@ FltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, else { std::string warning( "fltexp: Face is textured, but Texture2D StateAttribute is NULL." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); } } @@ -423,7 +423,7 @@ FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom else { std::string warning( "fltexp: Mesh is textured, but Texture2D StateAttribute is NULL." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); } } @@ -579,7 +579,7 @@ FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom ) if (!v3) { std::string warning( "fltexp: writeLocalVertexPool: VertexArray is not Vec3Array." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } @@ -755,7 +755,7 @@ FltExportVisitor::writeMultitexture( const osg::Geometry& geom ) { std::ostringstream warning; warning << "fltexp: No Texture2D for unit " << idx; - osg::notify( osg::WARN ) << warning.str() << std::endl; + OSG_WARN << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); } @@ -770,7 +770,7 @@ FltExportVisitor::writeMultitexture( const osg::Geometry& geom ) } void -FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom ) +FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom, const std::vector& indices ) { unsigned int numLayers( 0 ); uint32 flags( 0 ); @@ -794,32 +794,86 @@ FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom ) osg::Vec2 defaultCoord( 0., 0. ); // const osg::StateSet* ss = getCurrentStateSet(); + for( int vertexIdx=0; vertexIdx( geom.getTexCoordArray( idx ) ); + osg::ref_ptr t2 = dynamic_cast( t ); + if (!t2.valid()) + { + std::ostringstream warning; + warning << "fltexp: No Texture2D for unit " << idx; + OSG_WARN << warning.str() << std::endl; + _fltOpt->getWriteResult().warn( warning.str() ); + t2 = new osg::Vec2Array; + } + + const int size = t2->getNumElements(); + int vIdx = indices[ vertexIdx ]; + osg::Vec2& tc( defaultCoord ); + if (vIdx < size) + tc = ( *t2 )[ vIdx ]; + _records->writeFloat32( tc[ 0 ] ); + _records->writeFloat32( tc[ 1 ] ); + } + } + } +} + + +void +FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom, unsigned int first ) +{ + unsigned int numLayers( 0 ); + uint32 flags( 0 ); + unsigned int idx; for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { - osg::Array* t = const_cast( geom.getTexCoordArray( idx ) ); - osg::ref_ptr t2 = dynamic_cast( 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(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() ); - } + flags |= LAYER_1 >> (idx-1); + numLayers++; + } + } + if( numLayers == 0 ) + return; - const int size = t2->getNumElements(); - int vIdx; - for( vIdx=0; vIdxwriteInt16( (int16) UV_LIST_OP ); + _records->writeUInt16( length ); + _records->writeInt32( flags ); + + osg::Vec2 defaultCoord( 0., 0. ); + for( int vertexIdx=0; vertexIdx( geom.getTexCoordArray( idx ) ); + osg::ref_ptr t2 = dynamic_cast( 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 (t2->getNumElements() < first + numVerts) + { + std::ostringstream warning; + warning << "fltexp: Invalid number of texture coordinates for unit " << idx; + OSG_WARN << warning.str() << std::endl; + _fltOpt->getWriteResult().warn( warning.str() ); + } + + const int size = t2->getNumElements(); + int vIdx = first + vertexIdx; osg::Vec2& tc( defaultCoord ); if (vIdx < size) tc = (*t2)[ vIdx ]; @@ -1058,7 +1112,7 @@ FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Ge int numVerts = writeVertexList( indices, n ); first += n; - writeUVList( numVerts, geom ); + writeUVList( numVerts, geom, indices ); writePop(); } diff --git a/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp b/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp index 2d5154194..9b6dd61b6 100644 --- a/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp +++ b/src/osgPlugins/OpenFlight/expPrimaryRecords.cpp @@ -31,6 +31,7 @@ #include #include +#include // FIXME: This header was copied verbatim from the importer, with the only change // being that the symbols it defines are placed in namespace 'fltexp' instead @@ -282,7 +283,7 @@ FltExportVisitor::writeObject( const osg::Group& group, osgSim::ObjectRecordData if (!ord) { std::string warning( "fltexp: writeObject has invalid ObjectRecordData." ); - osg::notify( osg::WARN ) << warning << std::endl; + OSG_WARN << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } diff --git a/src/osgSim/MultiSwitch.cpp b/src/osgSim/MultiSwitch.cpp index 6a74644e6..3fc8ddd62 100644 --- a/src/osgSim/MultiSwitch.cpp +++ b/src/osgSim/MultiSwitch.cpp @@ -163,6 +163,7 @@ void MultiSwitch::expandToEncompassSwitchSet(unsigned int switchSet) // need to expand arrays. unsigned int originalSize = _values.size(); _values.resize(switchSet+1); + _valueNames.resize(switchSet+1); for(unsigned int i=originalSize;i<=switchSet;++i) { ValueList& values = _values[i]; @@ -232,3 +233,10 @@ void MultiSwitch::setValueList(unsigned int switchSet, const ValueList& values) _values[switchSet] = values; } + +void MultiSwitch::setValueName(unsigned int switchSet, const std::string& name) +{ + expandToEncompassSwitchSet(switchSet); + + _valueNames[switchSet] = name; +}