Dear Robert,

Thanks for the input. It is true that it does not render as it did before,
but it renders as the documentation says it should render. In my view, the
vertical bar was not correctly rotated. Instead of doing what the
documentation said (and which is logical: go along the Y axis), it still
was aligned with the x-axis (though sitting in the XZ plane rather than in
the XY plane). With my patch, it renders in the XY plane (as the Horizonal
one), but it goes along the Y axis.

To illustrate this, I have modified the example program to render both a
horizontal and a vertical in the scene so the difference can be seen.

Compared to my previous revision, I have fixed the flaw with the title
being in the wrong plane on the vertical one, and I have also repositioned
it to the top of the vertical one. Further, I have made the ticks on the
colortable shorter to make it more compact.

Please advice,


Kristofer

-- 
Kristofer Tingdahl, Ph. D.
CEO
dGB Earth Sciences
#include <osgSim/ScalarBar>
#include <osgText/Text>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <sstream>

using namespace osgSim;

ScalarBar::~ScalarBar()
{
}

std::string ScalarBar::ScalarPrinter::printScalar(float scalar)
{
    std::stringstream ostr;
    ostr<<scalar;
    return ostr.str();
}

void ScalarBar::setNumColors(int numColors)
{
    _numColors = numColors;
    createDrawables();
}

int ScalarBar::getNumColors() const
{
    return _numColors;
}

void ScalarBar::setNumLabels(int numLabels)
{
    _numLabels = numLabels;
    createDrawables();
}

int ScalarBar::getNumLabels() const
{
    return _numLabels;
}

void ScalarBar::setScalarsToColors(ScalarsToColors* stc)
{
    _stc = stc;
    createDrawables();
}

const ScalarsToColors* ScalarBar::getScalarsToColors() const
{
    return _stc.get();
}

void ScalarBar::setTitle(const std::string& title)
{
    _title = title;
    createDrawables();
}

const 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;
    createDrawables();
}

ScalarBar::Orientation ScalarBar::getOrientation() const
{
    return _orientation;
}

void ScalarBar::setAspectRatio(float aspectRatio)
{
    _aspectRatio = aspectRatio;
    createDrawables();
}

float ScalarBar::getAspectRatio() const
{
    return _aspectRatio;
}

void ScalarBar::setScalarPrinter(ScalarPrinter* sp)
{
    _sp = sp;
    createDrawables();
}

const ScalarBar::ScalarPrinter* ScalarBar::getScalarPrinter() const
{
    return _sp.get();
}


void ScalarBar::setTextProperties(const TextProperties& tp)
{
    _textProperties = tp;
    createDrawables();
}

const ScalarBar::TextProperties& ScalarBar::getTextProperties() const
{
    return _textProperties;
}


void ScalarBar::createDrawables()
{
    // Remove any existing Drawables
    _drawables.erase(_drawables.begin(), _drawables.end());

    if (_numColors==0) return;

    osg::Matrix matrix;
    if(_orientation==HORIZONTAL)
    {
        matrix = osg::Matrix::translate(_position);
    }
    else
    {
        matrix = osg::Matrix::rotate(osg::DegreesToRadians(90.0f),0.0f,0.0f,-1.0f) * osg::Matrix::translate(_position);
    }

    // 1. First the bar
    // =================
    osg::ref_ptr<osg::Geometry> 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<osg::Vec3Array> 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<osg::Vec4Array> 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<osg::Vec3Array> 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<osgText::Text*> 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 labely = arOffset + 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( 0, arOffset/2, 0 );
        }

        float titleY = (_numLabels>0) ? labely + characterSize : labely;

        // 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<osg::Vec3Array> 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), arOffset, 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<osg::Geometry> annotationGeom = new osg::Geometry();
    annotationGeom->addPrimitiveSet( new osg::DrawArrays(GL_LINES,0,annotVertices->size()) );
    annotationGeom->setVertexArray( annotVertices.get() );
    osg::ref_ptr<osg::Material> annotMaterial = new osg::Material;
    annotMaterial->setDiffuse( osg::Material::FRONT, _textProperties._color );
    annotationGeom->getOrCreateStateSet()->setAttribute( annotMaterial.get() );

    addDrawable( annotationGeom.get() );
}
/* OpenSceneGraph example, osgscalarbar.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Material>
#include <osg/Texture2D>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/BlendFunc>
#include <osg/ClearNode>
#include <osg/Projection>

#include <osgUtil/CullVisitor>

#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>

#include <osgSim/ScalarsToColors>
#include <osgSim/ColorRange>
#include <osgSim/ScalarBar>

#include <sstream>
#include <iostream>
#include <math.h>

using namespace osgSim;
using osgSim::ScalarBar;

#if defined(_MSC_VER)
// not have to have this pathway for just VS6.0 as its unable to handle the full
// ScalarBar::ScalarPrinter::printScalar scoping.

// Create a custom scalar printer
struct MyScalarPrinter: public ScalarBar::ScalarPrinter
{
    std::string printScalar(float scalar)
    {
        std::cout<<"In MyScalarPrinter::printScalar"<<std::endl;
        if(scalar==0.0f) return ScalarPrinter::printScalar(scalar)+" Bottom";
        else if(scalar==0.5f) return ScalarPrinter::printScalar(scalar)+" Middle";
        else if(scalar==1.0f) return ScalarPrinter::printScalar(scalar)+" Top";
        else return ScalarPrinter::printScalar(scalar);
    }
};
#else
// Create a custom scalar printer
struct MyScalarPrinter: public ScalarBar::ScalarPrinter
{
    std::string printScalar(float scalar)
    {
        std::cout<<"In MyScalarPrinter::printScalar"<<std::endl;
        if(scalar==0.0f) return ScalarBar::ScalarPrinter::printScalar(scalar)+" Bottom";
        else if(scalar==0.5f) return ScalarBar::ScalarPrinter::printScalar(scalar)+" Middle";
        else if(scalar==1.0f) return ScalarBar::ScalarPrinter::printScalar(scalar)+" Top";
        else return ScalarBar::ScalarPrinter::printScalar(scalar);
    }
};
#endif

osg::Node* createScalarBar(bool vertical)
{
#if 1
    //ScalarsToColors* stc = new ScalarsToColors(0.0f,1.0f);
    //ScalarBar* sb = new ScalarBar(2,3,stc,"STC_ScalarBar");

    // Create a custom color set
    std::vector<osg::Vec4> cs;
    cs.push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));   // R
    cs.push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));   // G
    cs.push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));   // G
    cs.push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));   // B
    cs.push_back(osg::Vec4(0.0f,1.0f,1.0f,1.0f));   // R


    ColorRange* cr = new ColorRange(0.0f,1.0f,cs);
    ScalarBar* sb = new ScalarBar(20, 11, cr,
                      vertical ? "Vertical" : "Horizontal",
                      vertical ? ScalarBar::VERTICAL : ScalarBar::HORIZONTAL,
                      0.1f, new MyScalarPrinter);
    sb->setScalarPrinter(new MyScalarPrinter);

    if ( !vertical )
    {
        sb->setPosition( osg::Vec3(0.5f,-0.5f,0));
    }

    return sb;
#else
    ScalarBar *sb = new ScalarBar;
    ScalarBar::TextProperties tp;
    tp._fontFile = "fonts/times.ttf";

    sb->setTextProperties(tp);

    return sb;
#endif

}

osg::Node * createScalarBar_HUD()
{
    osgSim::ScalarBar * geode = new osgSim::ScalarBar;
    osgSim::ScalarBar::TextProperties tp;
    tp._fontFile = "fonts/times.ttf";
    geode->setTextProperties(tp);
    osg::StateSet * stateset = geode->getOrCreateStateSet();
    stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

    stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
    stateset->setRenderBinDetails(11, "RenderBin");

    osg::MatrixTransform * modelview = new osg::MatrixTransform;
    modelview->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    osg::Matrixd matrix(osg::Matrixd::scale(1000,1000,1000) * osg::Matrixd::translate(120,10,0)); // I've played with these values a lot and it seems to work, but I have no idea why
    modelview->setMatrix(matrix);
    modelview->addChild(geode);

    osg::Projection * projection = new osg::Projection;
    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); // or whatever the OSG window res is
    projection->addChild(modelview);

    return projection; //make sure you delete the return sb line
}

int main(int , char **)
{
    // construct the viewer.
    osgViewer::Viewer viewer;

    osg::Group* group = new osg::Group;
    group->addChild(createScalarBar(true));
    group->addChild(createScalarBar(false));
    group->addChild(createScalarBar_HUD());

    // add model to viewer.
    viewer.setSceneData( group );

    return viewer.run();
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to