From b6c1c44bd0be1d512245d13a405c218fc9924fb4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 8 May 2004 21:33:25 +0000 Subject: [PATCH] From Paul Martz, "Changes to provide rudimentary support for OF 15.8 light point animation palettes. This change also includes light point palette override support for external references. This is the last of my code changes to support OF 15.8 in the flt loader. Barring bugs, of course, knock on wood. The gist of the animation palette code is to create ref_ptr'd osgSim::BlinkSequence objects for each palette entry, and then pass them on to osgSim::LightPoint for any OpenFlight light points that reference that palette entry. This should be conservative of memory (not that I expect the animation palette to be extremely large)." --- src/osgPlugins/flt/ExternalRecord.h | 3 +- src/osgPlugins/flt/FltFile.cpp | 53 +++++++++---- src/osgPlugins/flt/FltFile.h | 9 ++- .../flt/LightPointPaletteRecords.cpp | 67 ++++++++++++++++- src/osgPlugins/flt/LightPointPaletteRecords.h | 75 ++++++++++++++++++- src/osgPlugins/flt/Pool.cpp | 21 ++++++ src/osgPlugins/flt/Pool.h | 25 +++++++ src/osgPlugins/flt/flt2osg.cpp | 69 +++++++++++++++-- src/osgPlugins/flt/flt2osg.h | 2 + src/osgPlugins/flt/opcodes.h | 2 +- 10 files changed, 300 insertions(+), 26 deletions(-) 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