diff --git a/src/osgPlugins/flt/ExternalRecord.h b/src/osgPlugins/flt/ExternalRecord.h index 15723b5fb..65e5eaf31 100644 --- a/src/osgPlugins/flt/ExternalRecord.h +++ b/src/osgPlugins/flt/ExternalRecord.h @@ -55,7 +55,8 @@ class ExternalRecord : public PrimNodeRecord TEXTURE_PALETTE_OVERRIDE = BIT29, LINESTYLE_PALETTE_OVERRIDE = BIT28, SOUND_PALETTE_OVERRIDE = BIT27, - LIGHTSOURCE_PALETTE_OVERRIDE = BIT26 + LIGHTSOURCE_PALETTE_OVERRIDE = BIT26, + LIGHT_POINT_PALETTE_OVERRIDE = BIT25 }; protected: diff --git a/src/osgPlugins/flt/FltFile.cpp b/src/osgPlugins/flt/FltFile.cpp index 834e07838..4e5b04f86 100644 --- a/src/osgPlugins/flt/FltFile.cpp +++ b/src/osgPlugins/flt/FltFile.cpp @@ -24,7 +24,9 @@ using namespace flt; FltFile::FltFile( ColorPool* pColorPool, TexturePool* pTexturePool, - MaterialPool* pMaterialPool) + MaterialPool* pMaterialPool, + LtPtAppearancePool* pLtPtAppearancePool, + LtPtAnimationPool* pLtPtAnimationPool) { _useTextureAlphaForTransparancyBinning = true; _doUnitsConversion = true; @@ -69,14 +71,28 @@ FltFile::FltFile( setMaterialPool( new MaterialPool ); } + if (pLtPtAppearancePool && pLtPtAnimationPool) // Can only be non-NULL if parent is 15.8. + { + // use external light point appearance and animation palettes, ignore internal + _useInternalLtPtPalettes = false; + setLtPtAppearancePool( pLtPtAppearancePool ); + setLtPtAnimationPool( pLtPtAnimationPool ); + } + else + { + // If they aren't both set, then they must both be NULL. + assert( (pLtPtAppearancePool==NULL) && (pLtPtAppearancePool==NULL) ); + // use internal light point palettes + _useInternalLtPtPalettes = true; + setLtPtAppearancePool( new LtPtAppearancePool ); + setLtPtAnimationPool( new LtPtAnimationPool ); + } + // no support for external light palettes setLightPool( new LightPool ); // instances are always internally defined setInstancePool( new InstancePool ); - - // Light point appearances are always internally defined - setLtPtAppearancePool( new LtPtAppearancePool ); } @@ -191,26 +207,31 @@ bool FltFile::readFile(const std::string& fileName) ColorPool* pColorPool = NULL; TexturePool* pTexturePool = NULL; MaterialPool* pMaterialPool = NULL; + LtPtAppearancePool* pLtPtAppearancePool = NULL; + LtPtAnimationPool* pLtPtAnimationPool = NULL; std::string filename(pSExternal->szPath); osg::notify(osg::INFO) << "External=" << filename << std::endl; if (rec.getFlightVersion() > 13) { - if (pSExternal->dwFlags & ExternalRecord::COLOR_PALETTE_OVERRIDE) - pColorPool = NULL; - else + if (!(pSExternal->dwFlags & ExternalRecord::COLOR_PALETTE_OVERRIDE)) pColorPool = _pFltFile->getColorPool(); - if (pSExternal->dwFlags & ExternalRecord::TEXTURE_PALETTE_OVERRIDE) - pTexturePool = NULL; - else + if (!(pSExternal->dwFlags & ExternalRecord::TEXTURE_PALETTE_OVERRIDE)) pTexturePool = _pFltFile->getTexturePool(); - if (pSExternal->dwFlags & ExternalRecord::MATERIAL_PALETTE_OVERRIDE) - pMaterialPool = NULL; - else + if (!(pSExternal->dwFlags & ExternalRecord::MATERIAL_PALETTE_OVERRIDE)) pMaterialPool = _pFltFile->getMaterialPool(); + + if (rec.getFlightVersion() >= 1580) + { + if (!(pSExternal->dwFlags & ExternalRecord::LIGHT_POINT_PALETTE_OVERRIDE)) + { + pLtPtAppearancePool = _pFltFile->getLtPtAppearancePool(); + pLtPtAnimationPool = _pFltFile->getLtPtAnimationPool(); + } + } } #if REGISTER_FLT @@ -236,12 +257,14 @@ bool FltFile::readFile(const std::string& fileName) osgDB::PushAndPopDataPath tmpfile(pushAndPopPath); - pExternalFltFile = new FltFile(pColorPool, pTexturePool, pMaterialPool); + pExternalFltFile = new FltFile( pColorPool, pTexturePool, pMaterialPool, + pLtPtAppearancePool, pLtPtAnimationPool ); pExternalFltFile->readModel(filename); } Registry::instance()->addFltFile(filename, pExternalFltFile); #else - pExternalFltFile = new FltFile(pColorPool, pTexturePool, pMaterialPool); + pExternalFltFile = new FltFile( pColorPool, pTexturePool, pMaterialPool, + pLtPtAppearancePool, pLtPtAnimationPool ); pExternalFltFile->readModel(filename); #endif rec.setExternal(pExternalFltFile); diff --git a/src/osgPlugins/flt/FltFile.h b/src/osgPlugins/flt/FltFile.h index c36079119..3936df067 100644 --- a/src/osgPlugins/flt/FltFile.h +++ b/src/osgPlugins/flt/FltFile.h @@ -23,7 +23,9 @@ class FltFile : public osg::Referenced FltFile( ColorPool* pColorPool = NULL, TexturePool* pTexturePool = NULL, - MaterialPool* pMaterialPool = NULL); + MaterialPool* pMaterialPool = NULL, + LtPtAppearancePool* pLtPtAppearancePool = NULL, + LtPtAnimationPool* pLtPtAnimationPool = NULL); virtual osg::Object* readObject(const std::string& fileName); virtual osg::Node* readNode(const std::string& fileName); @@ -36,6 +38,7 @@ class FltFile : public osg::Referenced MaterialPool* getMaterialPool() { return _materialPool.get(); } InstancePool* getInstancePool() { return _instancePool.get(); } LtPtAppearancePool* getLtPtAppearancePool() { return _ltPtAppearancePool.get(); } + LtPtAnimationPool* getLtPtAnimationPool() { return _ltPtAnimationPool.get(); } void setColorPool(ColorPool* colorPool) { _colorPool = colorPool; } void setTexturePool(TexturePool* texturePool) { _texturePool = texturePool; } @@ -43,10 +46,12 @@ class FltFile : public osg::Referenced void setMaterialPool(MaterialPool* materialPool){ _materialPool = materialPool; } void setInstancePool(InstancePool* instancePool){ _instancePool = instancePool; } void setLtPtAppearancePool(LtPtAppearancePool* ltPtAppearancePool){ _ltPtAppearancePool = ltPtAppearancePool; } + void setLtPtAnimationPool(LtPtAnimationPool* ltPtAnimationPool){ _ltPtAnimationPool = ltPtAnimationPool; } inline bool useInternalColorPalette() const { return _useInternalColorPalette; } inline bool useInternalTexturePalette() const { return _useInternalTexturePalette; } inline bool useInternalMaterialPalette() const { return _useInternalMaterialPalette; } + inline bool useInternalLtPtPalettes() const { return _useInternalLtPtPalettes; } void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; } bool getUseTextureAlphaForTransparancyBinning() const { return _useTextureAlphaForTransparancyBinning; } @@ -82,6 +87,7 @@ class FltFile : public osg::Referenced bool _useInternalColorPalette; bool _useInternalTexturePalette; bool _useInternalMaterialPalette; + bool _useInternalLtPtPalettes; bool _useTextureAlphaForTransparancyBinning; bool _doUnitsConversion; ConvertUnits _desiredUnits; @@ -94,6 +100,7 @@ class FltFile : public osg::Referenced osg::ref_ptr _materialPool; osg::ref_ptr _instancePool; osg::ref_ptr _ltPtAppearancePool; + osg::ref_ptr _ltPtAnimationPool; }; diff --git a/src/osgPlugins/flt/LightPointPaletteRecords.cpp b/src/osgPlugins/flt/LightPointPaletteRecords.cpp index 583f5d90d..d14df1cb3 100644 --- a/src/osgPlugins/flt/LightPointPaletteRecords.cpp +++ b/src/osgPlugins/flt/LightPointPaletteRecords.cpp @@ -7,7 +7,7 @@ using namespace flt; //////////////////////////////////////////////////////////////////// // -// LightPointPaletteRecords +// LightPointAppearancePaletteRecords // //////////////////////////////////////////////////////////////////// @@ -68,3 +68,68 @@ void LtPtAppearancePaletteRecord::endian() ENDIAN( ltPtApp->lodScale ); } + + + +//////////////////////////////////////////////////////////////////// +// +// LightPointAnimationPaletteRecords +// +//////////////////////////////////////////////////////////////////// + +RegisterRecordProxy g_LtPtAnimationPaletteProxy; + +LtPtAnimationPaletteRecord::LtPtAnimationPaletteRecord() +{ +} + + +// virtual +LtPtAnimationPaletteRecord::~LtPtAnimationPaletteRecord() +{ +} + + +// virtual +void LtPtAnimationPaletteRecord::endian() +{ + SLightPointAnimationPalette* ltPtAnim = (SLightPointAnimationPalette*)getData(); + + ENDIAN( ltPtAnim->index ); + ENDIAN( ltPtAnim->period ); + ENDIAN( ltPtAnim->phaseDelay ); + ENDIAN( ltPtAnim->enabledPeriod ); + ENDIAN( ltPtAnim->axis[0] ); + ENDIAN( ltPtAnim->axis[1] ); + ENDIAN( ltPtAnim->axis[2] ); + ENDIAN( ltPtAnim->flags ); + ENDIAN( ltPtAnim->animType ); + ENDIAN( ltPtAnim->morseTiming ); + ENDIAN( ltPtAnim->wordRate ); + ENDIAN( ltPtAnim->charRate ); + ENDIAN( ltPtAnim->numSequences ); + + for (int idx=0; idx < ltPtAnim->numSequences; idx++) + { + SLightPointAnimationSequence* seq = sequence( idx ); + assert( seq ); + ENDIAN( seq->seqState ); + ENDIAN( seq->duration ); + ENDIAN( seq->seqColor ); + } +} + +SLightPointAnimationSequence* +LtPtAnimationPaletteRecord::sequence( int idx ) +{ + SLightPointAnimationPalette* ltPtAnim = (SLightPointAnimationPalette*)getData(); + if (idx >= ltPtAnim->numSequences) + return NULL; + + SLightPointAnimationSequence* seq = (SLightPointAnimationSequence*) + ( (char*)getData() + sizeof( SLightPointAnimationPalette ) ); + seq += idx; + + return seq; +} + diff --git a/src/osgPlugins/flt/LightPointPaletteRecords.h b/src/osgPlugins/flt/LightPointPaletteRecords.h index c99a4e01f..c66cd2d17 100644 --- a/src/osgPlugins/flt/LightPointPaletteRecords.h +++ b/src/osgPlugins/flt/LightPointPaletteRecords.h @@ -67,7 +67,6 @@ struct SLightPointAppearancePalette float32 lodScale; }; - class LtPtAppearancePaletteRecord : public AncillaryRecord { public: @@ -88,6 +87,80 @@ class LtPtAppearancePaletteRecord : public AncillaryRecord }; + +struct SLightPointAnimationPalette +{ + SRecHeader RecHeader; + int32 reserved_0; + char name[256]; + int32 index; + float32 period; // in seconds + float32 phaseDelay; // inb seconds, from start of period + float32 enabledPeriod; // time on, in seconds + float32 axis[3]; // for rotating animations + uint32 flags; // flags bits: 0 -- flashing + // 1 -- rotating + // 3 -- rotate counter clockwise + // 4-31 -- reserved + int32 animType; // animation type: 0 -- flashing sequence + // 1 -- rotating + // 2 -- strobe + // 3 -- Morse code + int32 morseTiming; // Morse timing: 0 -- standard timing + // 1 -- Farnsworth timing + int32 wordRate; // for Farnsworth timing + int32 charRate; // for Farnsworth timing + char morseString[1024]; + int32 numSequences; // for flashing sequences +}; +// Repeated numSequenses times: +struct SLightPointAnimationSequence +{ + uint32 seqState; // sequence state: 0 -- On + // 1 -- Off + // 2 -- Color Change + float32 duration; // duration of sequence in seconds + uint32 seqColor; // color, if state is On or Color Change +}; + +class LtPtAnimationPaletteRecord : public AncillaryRecord +{ + public: + + LtPtAnimationPaletteRecord(); + + virtual Record* clone() const { return new LtPtAnimationPaletteRecord(); } + virtual const char* className() const { return "LtPtAnimationPaletteRecord"; } + virtual int classOpcode() const { return LIGHT_PT_ANIMATION_PALETTE_OP; } + virtual size_t sizeofData() const { return sizeof(SLightPointAnimationPalette); } + virtual void accept(RecordVisitor& rv) { rv.apply(*this); } + + SLightPointAnimationSequence* sequence( int idx ); + + enum FlagsBits { + FLASHING = 0x80000000, + ROTATING = 0x40000000, + ROT_COUNTER_CLOCKWISE = 0x20000000 + }; + enum AnimationType { + SEQ_TYPE = 0, + ROT_TYPE = 1, + STROBE_TYPE = 2, + MORSE_TYPE = 3 + }; + enum SequenceState { + SEQ_ON = 0, + SEQ_OFF = 1, + SEQ_COLOR = 2 + }; + + protected: + virtual ~LtPtAnimationPaletteRecord(); + + virtual void endian(); +}; + + }; // end namespace flt diff --git a/src/osgPlugins/flt/Pool.cpp b/src/osgPlugins/flt/Pool.cpp index 23970a7c5..f7b63e287 100644 --- a/src/osgPlugins/flt/Pool.cpp +++ b/src/osgPlugins/flt/Pool.cpp @@ -305,5 +305,26 @@ void LtPtAppearancePool::add(int nIndex, PoolLtPtAppearance* appearance) } +LtPtAnimationPool::PoolLtPtAnimation* +LtPtAnimationPool::get( int nIndex ) +{ + if (nIndex < 0) + return NULL; + + AnimationMap::iterator fitr = _animationMap.find(nIndex); + if (fitr != _animationMap.end()) + return (*fitr).second.get(); + + return NULL; +} + + +void +LtPtAnimationPool::add(int nIndex, PoolLtPtAnimation* anim) +{ + _animationMap[nIndex] = anim; +} + + diff --git a/src/osgPlugins/flt/Pool.h b/src/osgPlugins/flt/Pool.h index 56ce21c7d..96ace4431 100644 --- a/src/osgPlugins/flt/Pool.h +++ b/src/osgPlugins/flt/Pool.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "AttrData.h" @@ -184,6 +185,30 @@ private: AppearanceMap _appearanceMap; }; +class LtPtAnimationPool : public osg::Referenced +{ +public: + struct PoolLtPtAnimation : public osg::Referenced + { + std::string _name; + osg::ref_ptr _blink; + }; + + LtPtAnimationPool() + {} + + PoolLtPtAnimation* get( int nIndex ); + void add( int nIndex, PoolLtPtAnimation* anim ); + +protected: + ~LtPtAnimationPool() {} + +private: + typedef std::map > AnimationMap; + AnimationMap _animationMap; +}; + + }; // end namespace flt #endif diff --git a/src/osgPlugins/flt/flt2osg.cpp b/src/osgPlugins/flt/flt2osg.cpp index 065f2622d..2e1229eca 100644 --- a/src/osgPlugins/flt/flt2osg.cpp +++ b/src/osgPlugins/flt/flt2osg.cpp @@ -239,6 +239,10 @@ osg::Group* ConvertFromFLT::visitAncillary(osg::Group& osgParent, osg::Group& os visitLtPtAppearancePalette(osgPrimary, (LtPtAppearancePaletteRecord*)child); break; + case LIGHT_PT_ANIMATION_PALETTE_OP: + visitLtPtAnimationPalette(osgPrimary, (LtPtAnimationPaletteRecord*)child); + break; + case VERTEX_PALETTE_OP: visitVertexPalette(osgPrimary, (VertexPaletteRecord*)child); break; @@ -770,6 +774,50 @@ void ConvertFromFLT::visitLtPtAppearancePalette(osg::Group& /*osgParent*/, LtPtA } } +void ConvertFromFLT::visitLtPtAnimationPalette(osg::Group& /*osgParent*/, LtPtAnimationPaletteRecord* rec) +{ + SLightPointAnimationPalette* ltPtAnim = (SLightPointAnimationPalette*)rec->getData(); + LtPtAnimationPool* pool = rec->getFltFile()->getLtPtAnimationPool(); + assert( pool ); + if (ltPtAnim && pool) + { + osg::ref_ptr entry = new LtPtAnimationPool::PoolLtPtAnimation; + + entry->_name = std::string( ltPtAnim->name ); + + // Support sequenced animations + if ( (ltPtAnim->animType == LtPtAnimationPaletteRecord::SEQ_TYPE) && + (ltPtAnim->numSequences > 0) ) + { + osg::ref_ptr b = new osgSim::BlinkSequence; + for (int idx=0; idxnumSequences; idx++) + { + SLightPointAnimationSequence* seq = rec->sequence( idx ); + osg::Vec4 color( 0.f, 0.f, 0.f, 0.f ); + if (seq->seqState != LtPtAnimationPaletteRecord::SEQ_OFF) + { + // Sequence state is On or Color Change, so set the color to non-black + ColorPool* pColorPool = rec->getFltFile()->getColorPool(); + color = pColorPool->getColor( seq->seqColor ); + } + b->addPulse( seq->duration, color ); + } + entry->_blink = b; + } + // Support strobe animations + else if (ltPtAnim->animType == LtPtAnimationPaletteRecord::STROBE_TYPE) + { + osg::ref_ptr b = new osgSim::BlinkSequence; + const float duration = .5f / ltPtAnim->period; + b->addPulse( duration, osg::Vec4( 0.f, 0.f, 0.f, 0.f ) ); + b->addPulse( duration, osg::Vec4( 1.f, 1.f, 1.f, 1.f ) ); + entry->_blink = b; + } + + pool->add( ltPtAnim->index, entry.get() ); + } +} + /*osgParent*/ void ConvertFromFLT::visitVertexPalette(osg::Group& , VertexPaletteRecord* rec) { @@ -2261,11 +2309,15 @@ void ConvertFromFLT::visitLightPointIndex(osg::Group& osgParent, LightPointIndex LtPtAppearancePool* appPool = rec->getFltFile()->getLtPtAppearancePool(); LtPtAppearancePool::PoolLtPtAppearance* ltPtApp = appPool->get( ltPtIdx->iAppearanceIndex ); if (!ltPtApp) - // Appearance index out of range - return; - - // TBD also get ltPtAnim record. - // LightPointAnimation not currently implemented + return; // Appearance index out of range + LtPtAnimationPool* animPool = rec->getFltFile()->getLtPtAnimationPool(); + LtPtAnimationPool::PoolLtPtAnimation* ltPtAnim = NULL; + if (ltPtIdx->iAnimationIndex >= 0) + { + ltPtAnim = animPool->get( ltPtIdx->iAnimationIndex ); + if (!ltPtAnim) + return; // Animation index out of range + } GeoSetBuilder pBuilder; DynGeoSet* dgset = pBuilder.getDynGeoSet(); @@ -2331,7 +2383,12 @@ void ConvertFromFLT::visitLightPointIndex(osg::Group& osgParent, LightPointIndex color = pColorPool->getColor( ltPtApp->_iBackColorIdx ); } - osgSim::LightPoint lp( true, coords[nl], color, ltPtApp->_sfIntensity, pointRadius); + osgSim::BlinkSequence* blink = NULL; + if (ltPtAnim && ltPtAnim->_blink.valid()) + blink = ltPtAnim->_blink.get(); + + osgSim::LightPoint lp( true, coords[nl], color, ltPtApp->_sfIntensity, pointRadius, + 0, blink ); if (directional) { diff --git a/src/osgPlugins/flt/flt2osg.h b/src/osgPlugins/flt/flt2osg.h index 07ee0f23e..10e6ea79c 100644 --- a/src/osgPlugins/flt/flt2osg.h +++ b/src/osgPlugins/flt/flt2osg.h @@ -31,6 +31,7 @@ class MaterialPaletteRecord; class OldMaterialPaletteRecord; class TexturePaletteRecord; class LtPtAppearancePaletteRecord; +class LtPtAnimationPaletteRecord; class VertexPaletteRecord; class VertexRecord; class NormalVertexRecord; @@ -137,6 +138,7 @@ class ConvertFromFLT void visitOldMaterialPalette(osg::Group& osgParent, OldMaterialPaletteRecord* rec); void visitTexturePalette(osg::Group& osgParent, TexturePaletteRecord* rec); void visitLtPtAppearancePalette(osg::Group& osgParent, LtPtAppearancePaletteRecord* rec); + void visitLtPtAnimationPalette(osg::Group& osgParent, LtPtAnimationPaletteRecord* rec); void visitVertexPalette(osg::Group& osgParent, VertexPaletteRecord* rec); void visitVertex(osg::Group& osgParent, VertexRecord* rec); void visitNormalVertex(osg::Group& osgParent, NormalVertexRecord* rec); diff --git a/src/osgPlugins/flt/opcodes.h b/src/osgPlugins/flt/opcodes.h index aa95ea1f4..81a142178 100644 --- a/src/osgPlugins/flt/opcodes.h +++ b/src/osgPlugins/flt/opcodes.h @@ -81,7 +81,7 @@ #define CURVE_OP 126 // ignored #define ROAD_CONSTRUCTION_OP 127 #define LIGHT_PT_APPEARANCE_PALETTE_OP 128 -#define LIGHT_PT_ANIMATION_PALETTE_OP 129 // ignored +#define LIGHT_PT_ANIMATION_PALETTE_OP 129 #define INDEXED_LIGHT_PT_OP 130 #define LIGHT_PT_SYSTEM_OP 131 #define INDEXED_STRING_OP 132 // ignored