From 7f94839e941b1b36dc13db48a5f2375363cf67f0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 2 Jun 2004 12:37:14 +0000 Subject: [PATCH] Added setPosition and setWidth methods into ScalarBar and changed the implementation to use these values to position and set the size of the scalar bar. Also made the characterSize value a float rather than the previous int. --- examples/osgscalarbar/osgscalarbar.cpp | 2 +- include/osgSim/ScalarBar | 43 ++++++-- src/osgSim/ScalarBar.cpp | 145 +++++++------------------ 3 files changed, 73 insertions(+), 117 deletions(-) diff --git a/examples/osgscalarbar/osgscalarbar.cpp b/examples/osgscalarbar/osgscalarbar.cpp index 4ee30ce3c..5fcf8d19a 100644 --- a/examples/osgscalarbar/osgscalarbar.cpp +++ b/examples/osgscalarbar/osgscalarbar.cpp @@ -55,7 +55,7 @@ osg::Node* createScalarBar() }; ColorRange* cr = new ColorRange(0.0f,1.0f,cs); - ScalarBar* sb = new ScalarBar(20, 11, cr, "ScalarBar", ScalarBar::VERTICAL, 4.0f, new MyScalarPrinter); + ScalarBar* sb = new ScalarBar(20, 11, cr, "ScalarBar", ScalarBar::VERTICAL, 0.1f, new MyScalarPrinter); sb->setScalarPrinter(new MyScalarPrinter); return sb; diff --git a/include/osgSim/ScalarBar b/include/osgSim/ScalarBar index dedfbf841..f8835232a 100644 --- a/include/osgSim/ScalarBar +++ b/include/osgSim/ScalarBar @@ -71,13 +71,13 @@ public: { std::string _fontFile; std::pair _fontResolution; - int _characterSize; + float _characterSize; osg::Vec4 _color; TextProperties(): _fontFile("fonts/arial.ttf"), _fontResolution(40,40), - _characterSize(0), + _characterSize(0.0f), _color(1.0f,1.0f,1.0f,1.0f) { } @@ -89,8 +89,10 @@ public: _numLabels(11), _stc(new ColorRange(0.0f,1.0f)), _title("Scalar Bar"), - _orientation(HORIZONTAL), + _position(0.0f,0.0f,0.0f), + _width(1.0f), _aspectRatio(0.03), + _orientation(HORIZONTAL), _sp(new ScalarPrinter) { createDrawables(); @@ -123,8 +125,10 @@ public: _numLabels(numLabels), _stc(stc), _title(title), - _orientation(orientation), + _position(0.0f,0.0f,0.0f), + _width(1.0f), _aspectRatio(aspectRatio), + _orientation(orientation), _sp(sp) { createDrawables(); @@ -136,8 +140,10 @@ public: _numLabels(rhs._numLabels), _stc(rhs._stc), // Consider clone for deep copy? _title(rhs._title), - _orientation(rhs._orientation), + _position(rhs._position), + _width(rhs._width), _aspectRatio(rhs._aspectRatio), + _orientation(rhs._orientation), _sp(rhs._sp), // Consider clone for deep copy? _textProperties(rhs._textProperties) { @@ -172,11 +178,18 @@ public: /** Get the title for the ScalarBar. */ std::string getTitle() const; - /** Set the orientation of the ScalarBar. @see Orientation */ - void setOrientation(ScalarBar::Orientation orientation); - /** Get the orientation of the ScalarBar. @see Orientation */ - ScalarBar::Orientation getOrientation() const; + /** Set the position of scalar bar's lower left corner.*/ + void setPosition(const osg::Vec3& pos); + + /** Get the position of scalar bar.*/ + const osg::Vec3& getPosition() const { return _position; } + + /** Set the width of the scalar bar.*/ + void setWidth(float width); + + /** Get the width of the scalar bar.*/ + float getWidth() { return _width; } /** Set the aspect ration (y/x) for the displayed bar. Bear in mind you may want to change this if you change the orientation. */ @@ -185,6 +198,14 @@ public: /** Get the aspect ration (y/x) for the displayed bar. */ float getAspectRatio() const; + + /** Set the orientation of the ScalarBar. @see Orientation */ + void setOrientation(ScalarBar::Orientation orientation); + + /** Get the orientation of the ScalarBar. @see Orientation */ + ScalarBar::Orientation getOrientation() const; + + /** Set a ScalarPrinter object for the ScalarBar. For every displayed ScalarBar label, the scalar value will be passed to the ScalarPrinter object to turn it into a string. Users may override the default ScalarPrinter @@ -209,8 +230,10 @@ private: int _numLabels; osg::ref_ptr _stc; std::string _title; - Orientation _orientation; + osg::Vec3 _position; + float _width; float _aspectRatio; + Orientation _orientation; osg::ref_ptr _sp; TextProperties _textProperties; diff --git a/src/osgSim/ScalarBar.cpp b/src/osgSim/ScalarBar.cpp index 05cf3d92e..6d5ac0886 100644 --- a/src/osgSim/ScalarBar.cpp +++ b/src/osgSim/ScalarBar.cpp @@ -56,6 +56,18 @@ std::string ScalarBar::getTitle() const return _title; } +void ScalarBar::setPosition(const osg::Vec3& pos) +{ + _position = pos; + createDrawables(); +} + +void ScalarBar::setWidth(float width) +{ + _width = width; + createDrawables(); +} + void ScalarBar::setOrientation(ScalarBar::Orientation orientation) { _orientation = orientation; @@ -101,43 +113,21 @@ const ScalarBar::TextProperties& ScalarBar::getTextProperties() const return _textProperties; } -namespace -{ - -struct MaxCoordLess -{ - enum Axis{X_AXIS, Y_AXIS, Z_AXIS}; - Axis _axis; - - MaxCoordLess(Axis axis): _axis(axis) {} - - bool operator()(const osgText::Text* d1, const osgText::Text* d2) - { - if(_axis == X_AXIS ) return d1->getBound().xMax() < d2->getBound().xMax(); - else if(_axis == Y_AXIS) return d1->getBound().yMax() < d2->getBound().yMax(); - else if(_axis == Z_AXIS) return d1->getBound().zMax() < d2->getBound().zMax(); - - return false; - } -}; - -struct AlignCentreOnYValue -{ - float _y; - AlignCentreOnYValue(float y): _y(y) {} - void operator()(osgText::Text* t) - { - t->setPosition(osg::Vec3(t->getBound().center().x(), _y, t->getBound().center().z())); - t->setAlignment(osgText::Text::CENTER_CENTER); - } -}; - -} void ScalarBar::createDrawables() { // Remove any existing Drawables _drawables.erase(_drawables.begin(), _drawables.end()); + + osg::Matrix matrix; + if(_orientation==HORIZONTAL) + { + matrix = osg::Matrix::translate(_position); + } + else + { + matrix = osg::Matrix::rotate(osg::DegreesToRadians(90.0f),1.0f,0.0f,0.0f) * osg::Matrix::translate(_position); + } // 1. First the bar // ================= @@ -152,34 +142,16 @@ void ScalarBar::createDrawables() vs->reserve(2*(_numColors+1)); float incr = (_stc->getMax() - _stc->getMin()) / _numColors; - float arOffset; - if(_orientation==HORIZONTAL) - { - arOffset = _numColors * incr * _aspectRatio; // Bar height for a horizontal bar - } - else - { - arOffset = (_numColors*incr)/_aspectRatio; // Bar width for a vertical bar - } + float xincr = (_width) / _numColors; + float arOffset = _width * _aspectRatio; int i; for(i=1; i<=_numColors; ++i) { - // Make a quad - if(_orientation==HORIZONTAL) - { - vs->push_back(osg::Vec3(_stc->getMin() + (i-1) * incr, 0.0f, 0.0f)); - vs->push_back(osg::Vec3(_stc->getMin() + (i-1) * incr, arOffset, 0.0f)); - vs->push_back(osg::Vec3(_stc->getMin() + i * incr, arOffset, 0.0f)); - vs->push_back(osg::Vec3(_stc->getMin() + i * incr, 0.0f, 0.0f)); - } - else - { - vs->push_back(osg::Vec3(0.0f, _stc->getMin() + (i-1) * incr, 0.0f)); - vs->push_back(osg::Vec3(arOffset, _stc->getMin() + (i-1) * incr, 0.0f)); - vs->push_back(osg::Vec3(arOffset, _stc->getMin() + i * incr, 0.0f)); - vs->push_back(osg::Vec3(0.0f, _stc->getMin() + i * incr, 0.0f)); - } + 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()); @@ -198,7 +170,7 @@ void ScalarBar::createDrawables() // Normal osg::ref_ptr ns(new osg::Vec3Array); - ns->push_back(osg::Vec3(0.0f,0.0f,1.0f)); + ns->push_back(osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix)); bar->setNormalArray(ns.get()); bar->setNormalBinding(osg::Geometry::BIND_OVERALL); @@ -212,12 +184,13 @@ void ScalarBar::createDrawables() // Check the character size, if it's 0, estimate a good character size float characterSize = _textProperties._characterSize; - if(characterSize == 0) characterSize = ((_stc->getMax()-_stc->getMin())*0.3)/_numLabels; + 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 = (_stc->getMax()-_stc->getMin())/(_numLabels-1); + float labelxIncr = (_width)/(_numLabels-1); for(i=0; i<_numLabels; ++i) { osgText::Text* text = new osgText::Text; @@ -227,29 +200,15 @@ void ScalarBar::createDrawables() text->setCharacterSize(characterSize); text->setText(_sp->printScalar(_stc->getMin()+(i*labelIncr))); - if(_orientation == HORIZONTAL) - { - text->setPosition(osg::Vec3(_stc->getMin() + (i*labelIncr), arOffset, 0.0f)); - text->setAlignment(osgText::Text::CENTER_BOTTOM); - } - else - { - text->setPosition(osg::Vec3(arOffset, _stc->getMin() + (i*labelIncr), 0.0f)); - text->setAlignment(osgText::Text::LEFT_CENTER); - } + text->setPosition(osg::Vec3((i*labelxIncr), arOffset, 0.0f)*matrix); + text->setAlignment(osgText::Text::CENTER_BASE_LINE); + text->setAxisAlignment( (_orientation==HORIZONTAL) ? osgText::Text::XY_PLANE : osgText::Text::XZ_PLANE ); addDrawable(text); texts[i] = text; } - // Make sure the text labels are all properly aligned - different words will have a different - // vertical alignment depending on the letters used in the labels. E.g. a 'y' has a dangling tail. - if(_orientation == HORIZONTAL) - { - std::vector::iterator maxYIt = std::max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::Y_AXIS)); - std::for_each(texts.begin(), texts.end(), AlignCentreOnYValue((*maxYIt)->getBound().center().y())); - } // 3. And finally the title // ======================== @@ -263,38 +222,12 @@ void ScalarBar::createDrawables() text->setCharacterSize(characterSize); text->setText(_title); - if(_orientation==HORIZONTAL) - { - // Horizontal bars have the title above the scalar bar and the labels. - // Need to move the title above any labels, using maximum y value of the - // existing text objects + float titleY = (_numLabels>0) ? arOffset + characterSize : arOffset; - std::vector::iterator maxYIt = std::max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::Y_AXIS)); - - float titleY; - if(maxYIt != texts.end()) titleY = (*maxYIt)->getBound().yMax() * 1.1f; - else titleY = arOffset; // No labels, so just use arOffset - - // Position the title at the middle of the bar above any labels. - text->setPosition(osg::Vec3(_stc->getMin() + ((_stc->getMax()-_stc->getMin())/2.0f), titleY, 0.0f)); - text->setAlignment(osgText::Text::CENTER_BOTTOM); - } - else if(_orientation==VERTICAL) - { - // Vertical bars have the title to the right of the scalar bar and the labels. - // Need to move the title out beyond any labels, using the maximum x value of the - // existing text objects - - std::vector::iterator maxXIt = std::max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::X_AXIS)); - - float titleX; - if(maxXIt != texts.end()) titleX = (*maxXIt)->getBound().xMax() * 1.1f; - else titleX = arOffset; // No labels, so just use arOffset - - // Position the title in the at the middle of the bar, to the right of any labels. - text->setPosition(osg::Vec3(titleX, _stc->getMin() + ((_stc->getMax()-_stc->getMin())/2.0f), 0.0f)); - text->setAlignment(osgText::Text::LEFT_CENTER); - } + // Position the title at the middle of the bar above any labels. + text->setPosition(osg::Vec3((_width/2.0f), titleY, 0.0f)*matrix); + text->setAlignment(osgText::Text::CENTER_BASE_LINE); + text->setAxisAlignment( (_orientation==HORIZONTAL) ? osgText::Text::XY_PLANE : osgText::Text::XZ_PLANE ); addDrawable(text); }