#include #include #include #include #include #include using namespace osgSim; ScalarBar::~ScalarBar() { } std::string ScalarBar::ScalarPrinter::printScalar(float scalar) { std::stringstream ostr; ostr< bar = new osg::Geometry(); // Create the bar - created in 'real' coordinate space the moment, // with xyz values reflecting those of the actual scalar values in play. // FIXME: Consider positioning at origin! Should be easy enough to do. // Vertices osg::ref_ptr vs(new osg::Vec3Array); vs->reserve(4*_numColors); float incr = (_stc->getMax() - _stc->getMin()) / _numColors; float xincr = (_width) / _numColors; float arOffset = _width * _aspectRatio; int i; for(i=1; i<=_numColors; ++i) { vs->push_back(osg::Vec3((i-1) * xincr, 0.0f, 0.0f)*matrix); vs->push_back(osg::Vec3((i-1) * xincr, arOffset, 0.0f)*matrix); vs->push_back(osg::Vec3(i * xincr, arOffset, 0.0f)*matrix); vs->push_back(osg::Vec3(i * xincr, 0.0f, 0.0f)*matrix); } bar->setVertexArray(vs.get()); // Colours osg::ref_ptr cs(new osg::Vec4Array); cs->reserve(4*_numColors); const float halfIncr = incr*0.5; for(i=0; i<_numColors; ++i) { // We add half an increment to the color look-up to get the color // square in the middle of the 'block'. osg::Vec4 c = _stc->getColor(_stc->getMin() + (i*incr) + halfIncr); cs->push_back(c); cs->push_back(c); cs->push_back(c); cs->push_back(c); } bar->setColorArray(cs.get(), osg::Array::BIND_PER_VERTEX); // Normal osg::ref_ptr ns(new osg::Vec3Array); ns->push_back(osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix)); bar->setNormalArray(ns.get(), osg::Array::BIND_OVERALL); // The Quad strip that represents the bar bar->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,vs->size())); bar->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1,1), osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON ); addDrawable(bar.get()); #define CHARACTER_OFFSET_FACTOR (0.3f) // 2. Then the text labels // ======================= // Check the character size, if it's 0, estimate a good character size float characterSize = _textProperties._characterSize; if(characterSize == 0) characterSize = _width * 0.03f; osgText::Font* font = osgText::readFontFile(_textProperties._fontFile.c_str()); std::vector texts(_numLabels); // We'll need to collect pointers to these for later float labelIncr = (_numLabels>0) ? (_stc->getMax()-_stc->getMin())/(_numLabels-1) : 0.0f; float labelxIncr = (_numLabels>0) ? (_width)/(_numLabels-1) : 0.0f; const float labelStickStartY = _orientation==HORIZONTAL ? arOffset : 0; const float labelY = labelStickStartY + (_orientation==HORIZONTAL ? characterSize : -characterSize) * CHARACTER_OFFSET_FACTOR; for(i=0; i<_numLabels; ++i) { osgText::Text* text = new osgText::Text; text->setFont(font); text->setColor(_textProperties._color); text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second); text->setCharacterSize(characterSize); text->setText(_sp->printScalar(_stc->getMin()+(i*labelIncr))); text->setPosition(osg::Vec3((i*labelxIncr), labelY, 0.0f)*matrix); text->setAlignment( (_orientation==HORIZONTAL) ? osgText::Text::CENTER_BASE_LINE : osgText::Text::LEFT_CENTER); addDrawable(text); texts[i] = text; } // 3. The title // ============ if(_title != "") { osgText::Text* text = new osgText::Text; text->setFont(font); text->setColor(_textProperties._color); text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second); text->setCharacterSize(characterSize); text->setText(_title); osg::Vec3 titlePos; if ( _orientation==HORIZONTAL ) { const float titleY = (_numLabels>0) ? labelY + characterSize : labelY; titlePos = osg::Vec3((_width/2.0f), titleY, 0.0f); } else { titlePos = osg::Vec3(_width+characterSize*0.5, arOffset*0.5, 0 ); } // Position the title at the middle of the bar above any labels. text->setPosition(titlePos*matrix); text->setAlignment( _orientation==HORIZONTAL ? osgText::Text::CENTER_BASE_LINE : osgText::Text::CENTER_BOTTOM); addDrawable(text); } // 4. The rectangular border and sticks // ==================================== osg::ref_ptr annotVertices = new osg::Vec3Array; //Border annotVertices->push_back( osg::Vec3(0.0f,0.0f,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(0.0f,arOffset,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(0.0f,arOffset,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(_width,arOffset,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(_width,arOffset,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(_width,0.0f,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(_width,0.0f,0.0f) * matrix ); annotVertices->push_back( osg::Vec3(0.0f,0.0f,0.0f) * matrix ); //Sticks for(i=0; i<_numLabels; ++i) { const osg::Vec3 p1(osg::Vec3((i*labelxIncr), labelStickStartY, 0.0f)*matrix); const osg::Vec3 p2(osg::Vec3((i*labelxIncr), labelY, 0.0f)*matrix); annotVertices->push_back( p1 ); annotVertices->push_back( p2 ); } osg::ref_ptr annotationGeom = new osg::Geometry(); annotationGeom->addPrimitiveSet( new osg::DrawArrays(GL_LINES,0,annotVertices->size()) ); annotationGeom->setVertexArray( annotVertices.get() ); osg::ref_ptr annotMaterial = new osg::Material; annotMaterial->setDiffuse( osg::Material::FRONT, _textProperties._color ); annotationGeom->getOrCreateStateSet()->setAttribute( annotMaterial.get() ); addDrawable( annotationGeom.get() ); }