diff --git a/src/osgPlugins/txp/ReaderWriterTXP.cpp b/src/osgPlugins/txp/ReaderWriterTXP.cpp index 2dba9d9e6..acc1a8193 100644 --- a/src/osgPlugins/txp/ReaderWriterTXP.cpp +++ b/src/osgPlugins/txp/ReaderWriterTXP.cpp @@ -216,6 +216,12 @@ TXPArchive *ReaderWriterTXP::getArchive(int id, const std::string& dir) return NULL; } + if (archive->loadTextStyles() == false) + { + ReaderWriterTXPERROR("getArchive()") << "failed to load text styles from archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + archive->setId(id); _archives[id] = archive; diff --git a/src/osgPlugins/txp/TXPArchive.cpp b/src/osgPlugins/txp/TXPArchive.cpp index 1721739cf..ce1c47841 100644 --- a/src/osgPlugins/txp/TXPArchive.cpp +++ b/src/osgPlugins/txp/TXPArchive.cpp @@ -518,6 +518,28 @@ bool TXPArchive::loadLightAttributes() return true; } +bool TXPArchive::loadTextStyles() +{ + const trpgTextStyleTable *textStyleTable = GetTextStyleTable(); + if (!textStyleTable) return false; + + _fonts.resize(textStyleTable->GetNumStyle()); + for (int i = 0; i < textStyleTable->GetNumStyle(); i++) + { + const trpgTextStyle *textStyle = textStyleTable->GetStyleRef(i); + if (!textStyle) continue; + + const std::string *fontName = textStyle->GetFont(); + if (!fontName) continue; + + osg::ref_ptr< osgText::Font > font = osgText::readFontFile(*fontName + ".ttf"); + + _fonts[i] = font; + } + + return true; +} + void TXPArchive::addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback, const osg::Vec3& att) { DefferedLightAttribute la; @@ -600,17 +622,17 @@ osg::Group* TXPArchive::getTileContent( osg::Group *tileGroup = _parser->parseScene(buf,_gstates,_models,realMinRange,realMaxRange,usedMaxRange); tileCenter = _parser->getTileCenter(); - // Prune - unsigned int i = 0; - for (i = 0; i < _gstates.size(); i++) - { - if (_gstates[i].get() && (_gstates[i]->referenceCount()==1)) _gstates[i] = 0; - } + // Prune + unsigned int i = 0; + for (i = 0; i < _gstates.size(); i++) + { + if (_gstates[i].valid() && (_gstates[i]->referenceCount()==1)) _gstates[i] = 0; + } - for (i = 0; i < _textures.size(); i++) - { - if (_textures[i].get() && (_textures[i]->referenceCount()==1)) _textures[i] = 0; - } + for (i = 0; i < _textures.size(); i++) + { + if (_textures[i].valid() && (_textures[i]->referenceCount()==1)) _textures[i] = 0; + } return tileGroup; } @@ -630,4 +652,3 @@ bool TXPArchive::getLODSize(int lod, int& x, int& y) return true; } - diff --git a/src/osgPlugins/txp/TXPArchive.h b/src/osgPlugins/txp/TXPArchive.h index a2fd70948..f5769e252 100644 --- a/src/osgPlugins/txp/TXPArchive.h +++ b/src/osgPlugins/txp/TXPArchive.h @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -79,6 +80,10 @@ public: // Load the light attribs from the archive bool loadLightAttributes(); + + // Load the text styles from the archive + bool loadTextStyles(); + inline std::vector< osg::ref_ptr >& getStyles() { return _fonts; } // Add light attrib void addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback , const osg::Vec3& attitude); @@ -169,16 +174,19 @@ protected: osg::ref_ptr _parser; // Textures - std::vector< osg::ref_ptr > _textures; + std::vector< osg::ref_ptr > _textures; // States - std::vector< osg::ref_ptr > _gstates; + std::vector< osg::ref_ptr > _gstates; // Models - std::vector< osg::ref_ptr > _models; + std::vector< osg::ref_ptr > _models; // Light attributes vector - std::vector _lights; + std::vector _lights; + + // Text styles / Fonts + std::vector< osg::ref_ptr > _fonts; // OpenThreads::Mutex _mutex; diff --git a/src/osgPlugins/txp/TXPParser.cpp b/src/osgPlugins/txp/TXPParser.cpp index e59d276ad..e35da7474 100644 --- a/src/osgPlugins/txp/TXPParser.cpp +++ b/src/osgPlugins/txp/TXPParser.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "TXPParser.h" #include "TXPArchive.h" @@ -47,6 +48,7 @@ _usedMaxRange(0.0) AddCallback(TRPG_BILLBOARD,new billboardRead(this)); AddCallback(TRPG_LIGHT,new lightRead(this)); AddCallback(TRPG_LAYER,new layerRead(this)); + AddCallback(TRPG_LABEL,new labelRead(this)); AddCallback(TRPGTILEHEADER,new tileHeaderRead(this)); if (getenv("OSG_TXP_DEFAULT_MAX_ANISOTROPY")) @@ -747,6 +749,91 @@ void* layerRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) #endif } +//---------------------------------------------------------------------------- +// +// Label Reader Class +// +//---------------------------------------------------------------------------- +void* labelRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) +{ + trpgLabel label; + if (!label.Read(buf)) return NULL; + + const std::string *labelText = label.GetText(); + if (!labelText) return (void*)1; + + osg::Vec3 pos(label.GetLocation().x, label.GetLocation().y, label.GetLocation().z); + + osg::ref_ptr< osg::Geode > textGeode = new osg::Geode; + _parse->getCurrTop()->addChild(textGeode.get()); + + osg::ref_ptr< osgText::Text > text = new osgText::Text; + textGeode->addDrawable(text.get()); + + // Text + text->setText(*labelText); + // Position + text->setPosition(pos); + // Alignment + switch (label.GetAlignment()) + { + case trpgLabel::Left: + text->setAlignment(osgText::Text::LEFT_BOTTOM); + break; + case trpgLabel::Right: + text->setAlignment(osgText::Text::RIGHT_BOTTOM); + break; + default: + text->setAlignment(osgText::Text::CENTER_BOTTOM); + } + // Axis alignment + text->setAxisAlignment(osgText::Text::XY_PLANE); + + const trpgLabelPropertyTable *labelPropertyTable = _parse->getArchive()->GetLabelPropertyTable(); + const trpgLabelProperty *labelProperty = labelPropertyTable ? + labelPropertyTable->GetPropertyRef(label.GetProperty()) : 0; + + if (labelProperty) + { + const trpgTextStyleTable *textStyleTable = _parse->getArchive()->GetTextStyleTable(); + if (!textStyleTable) return (void*)1; + + const trpgTextStyle *textStyle = textStyleTable->GetStyleRef(labelProperty->GetFontStyle()); + if (!textStyle) return (void*)1; + + // Size + text->setCharacterSize(textStyle->GetCharacterSize()*label.GetScale()); + text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS); + // Font + text->setFont(_parse->getArchive()->getStyles()[labelProperty->GetFontStyle()].get()); + + // Type + switch (labelProperty->GetType()) + { + case trpgLabelProperty::Billboard: + text->setAxisAlignment(osgText::Text::SCREEN); + break; + case trpgLabelProperty::VertBillboard: + break; + case trpgLabelProperty::Panel: + break; + case trpgLabelProperty::Cube: + break; + case trpgLabelProperty::MaxLabelType: + break; + } + } + +#if 1 + osg::TessellationHints* hints = new osg::TessellationHints; + hints->setDetailRatio(0.5f); + + textGeode->addDrawable(new osg::ShapeDrawable(new osg::Cone(pos,1.f,50.f),hints)); +#endif + + return (void*)1; +} + //---------------------------------------------------------------------------- // // Geometry Reader Class @@ -947,10 +1034,10 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if( local ) tmp_ss = (*_parse->getLocalMaterials())[matId]; else - { - _parse->loadMaterial(matId); - tmp_ss = (*_parse->getMaterials())[matId]; - } + { + _parse->loadMaterial(matId); + tmp_ss = (*_parse->getMaterials())[matId]; + } if(sset.valid()) { if(tmp_ss.valid()){ diff --git a/src/osgPlugins/txp/TXPParser.h b/src/osgPlugins/txp/TXPParser.h index 654f2940d..a799620e3 100644 --- a/src/osgPlugins/txp/TXPParser.h +++ b/src/osgPlugins/txp/TXPParser.h @@ -449,6 +449,17 @@ protected: TXPParser *_parse; }; +//---------------------------------------------------------------------------- +class labelRead: public trpgr_Callback +{ +public: + labelRead(TXPParser *in_parse) : _parse(in_parse) + {}; + void *Parse(trpgToken tok,trpgReadBuffer &buf); +protected: + TXPParser *_parse; +}; + } // namespace #endif // __TXPPARSER_H_