root/OpenSceneGraph/trunk/src/osgSim/ScalarBar.cpp @ 14047

Revision 14047, 8.3 kB (checked in by robert, 9 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgSim/ScalarBar>
2#include <osgText/Text>
3#include <osg/Geometry>
4#include <osg/Material>
5#include <osg/PolygonOffset>
6#include <sstream>
7
8using namespace osgSim;
9
10ScalarBar::~ScalarBar()
11{
12}
13
14std::string ScalarBar::ScalarPrinter::printScalar(float scalar)
15{
16    std::stringstream ostr;
17    ostr<<scalar;
18    return ostr.str();
19}
20
21void ScalarBar::setNumColors(int numColors)
22{
23    _numColors = numColors;
24    createDrawables();
25}
26
27int ScalarBar::getNumColors() const
28{
29    return _numColors;
30}
31
32void ScalarBar::setNumLabels(int numLabels)
33{
34    _numLabels = numLabels;
35    createDrawables();
36}
37
38int ScalarBar::getNumLabels() const
39{
40    return _numLabels;
41}
42
43void ScalarBar::setScalarsToColors(ScalarsToColors* stc)
44{
45    _stc = stc;
46    createDrawables();
47}
48
49const ScalarsToColors* ScalarBar::getScalarsToColors() const
50{
51    return _stc.get();
52}
53
54void ScalarBar::setTitle(const std::string& title)
55{
56    _title = title;
57    createDrawables();
58}
59
60const std::string& ScalarBar::getTitle() const
61{
62    return _title;
63}
64
65void ScalarBar::setPosition(const osg::Vec3& pos)
66{
67    _position = pos;
68    createDrawables();
69}
70
71void ScalarBar::setWidth(float width)
72{
73    _width = width;
74    createDrawables();
75}
76
77void ScalarBar::setOrientation(ScalarBar::Orientation orientation)
78{
79    _orientation = orientation;
80    createDrawables();
81}
82
83ScalarBar::Orientation ScalarBar::getOrientation() const
84{
85    return _orientation;
86}
87
88void ScalarBar::setAspectRatio(float aspectRatio)
89{
90    _aspectRatio = aspectRatio;
91    createDrawables();
92}
93
94float ScalarBar::getAspectRatio() const
95{
96    return _aspectRatio;
97}
98
99void ScalarBar::setScalarPrinter(ScalarPrinter* sp)
100{
101    _sp = sp;
102    createDrawables();
103}
104
105const ScalarBar::ScalarPrinter* ScalarBar::getScalarPrinter() const
106{
107    return _sp.get();
108}
109
110
111void ScalarBar::setTextProperties(const TextProperties& tp)
112{
113    _textProperties = tp;
114    createDrawables();
115}
116
117const ScalarBar::TextProperties& ScalarBar::getTextProperties() const
118{
119    return _textProperties;
120}
121
122
123void ScalarBar::createDrawables()
124{
125    // Remove any existing Drawables
126    _drawables.erase(_drawables.begin(), _drawables.end());
127
128    if (_numColors==0) return;
129
130    osg::Matrix matrix;
131    if(_orientation==HORIZONTAL)
132    {
133        matrix = osg::Matrix::translate(_position);
134    }
135    else
136    {
137        matrix = osg::Matrix::rotate(osg::DegreesToRadians(90.0f),0.0f,0.0f,-1.0f) * osg::Matrix::translate(_position);
138    }
139
140    // 1. First the bar
141    // =================
142    osg::ref_ptr<osg::Geometry> bar = new osg::Geometry();
143
144    // Create the bar - created in 'real' coordinate space the moment,
145    // with xyz values reflecting those of the actual scalar values in play.
146    // FIXME: Consider positioning at origin! Should be easy enough to do.
147
148    // Vertices
149    osg::ref_ptr<osg::Vec3Array> vs(new osg::Vec3Array);
150    vs->reserve(4*_numColors);
151
152    float incr = (_stc->getMax() - _stc->getMin()) / _numColors;
153    float xincr = (_width) / _numColors;
154    float arOffset = _width * _aspectRatio;
155
156    int i;
157    for(i=1; i<=_numColors; ++i)
158    {
159        vs->push_back(osg::Vec3((i-1) * xincr, 0.0f,     0.0f)*matrix);
160        vs->push_back(osg::Vec3((i-1) * xincr, arOffset, 0.0f)*matrix);
161        vs->push_back(osg::Vec3(i     * xincr, arOffset, 0.0f)*matrix);
162        vs->push_back(osg::Vec3(i     * xincr, 0.0f,     0.0f)*matrix);
163    }
164    bar->setVertexArray(vs.get());
165
166    // Colours
167    osg::ref_ptr<osg::Vec4Array> cs(new osg::Vec4Array);
168    cs->reserve(4*_numColors);
169    const float halfIncr = incr*0.5;
170    for(i=0; i<_numColors; ++i)
171    {
172        // We add half an increment to the color look-up to get the color
173        // square in the middle of the 'block'.
174        osg::Vec4 c = _stc->getColor(_stc->getMin() + (i*incr)  + halfIncr);
175        cs->push_back(c);
176        cs->push_back(c);
177        cs->push_back(c);
178        cs->push_back(c);
179    }
180
181    bar->setColorArray(cs.get(), osg::Array::BIND_PER_VERTEX);
182
183    // Normal
184    osg::ref_ptr<osg::Vec3Array> ns(new osg::Vec3Array);
185    ns->push_back(osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix));
186    bar->setNormalArray(ns.get(), osg::Array::BIND_OVERALL);
187
188    // The Quad strip that represents the bar
189    bar->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,vs->size()));
190    bar->getOrCreateStateSet()->setAttributeAndModes( new osg::PolygonOffset(1,1),
191                            osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON );
192
193    addDrawable(bar.get());
194
195#define CHARACTER_OFFSET_FACTOR (0.3f)
196
197    // 2. Then the text labels
198    // =======================
199
200    // Check the character size, if it's 0, estimate a good character size
201    float characterSize = _textProperties._characterSize;
202    if(characterSize == 0) characterSize = _width * 0.03f;
203
204    osgText::Font* font = osgText::readFontFile(_textProperties._fontFile.c_str());
205
206    std::vector<osgText::Text*> texts(_numLabels);      // We'll need to collect pointers to these for later
207    float labelIncr = (_numLabels>0) ? (_stc->getMax()-_stc->getMin())/(_numLabels-1) : 0.0f;
208    float labelxIncr = (_numLabels>0) ? (_width)/(_numLabels-1) : 0.0f;
209    const float labely = arOffset + characterSize*CHARACTER_OFFSET_FACTOR;
210
211    for(i=0; i<_numLabels; ++i)
212    {
213        osgText::Text* text = new osgText::Text;
214        text->setFont(font);
215        text->setColor(_textProperties._color);
216        text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second);
217        text->setCharacterSize(characterSize);
218        text->setText(_sp->printScalar(_stc->getMin()+(i*labelIncr)));
219
220        text->setPosition(osg::Vec3((i*labelxIncr), labely, 0.0f)*matrix);
221        text->setAlignment( (_orientation==HORIZONTAL) ? osgText::Text::CENTER_BASE_LINE : osgText::Text::LEFT_CENTER);
222
223        addDrawable(text);
224
225        texts[i] = text;
226    }
227
228    // 3. The title
229    // ============
230
231    if(_title != "")
232    {
233        osgText::Text* text = new osgText::Text;
234        text->setFont(font);
235        text->setColor(_textProperties._color);
236        text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second);
237        text->setCharacterSize(characterSize);
238        text->setText(_title);
239
240        osg::Vec3 titlePos;
241        if ( _orientation==HORIZONTAL )
242        {
243            const float titleY = (_numLabels>0) ? labely + characterSize : labely;
244            titlePos = osg::Vec3((_width/2.0f), titleY, 0.0f);
245        }
246        else
247        {
248            titlePos = osg::Vec3( 0, arOffset/2, 0 );
249        }
250
251        float titleY = (_numLabels>0) ? labely + characterSize : labely;
252
253        // Position the title at the middle of the bar above any labels.
254        text->setPosition(titlePos*matrix);
255        text->setAlignment(
256            _orientation==HORIZONTAL ? osgText::Text::CENTER_BASE_LINE : osgText::Text::CENTER_BOTTOM);
257
258        addDrawable(text);
259    }
260
261    // 4. The rectangular border and sticks
262    // ====================================
263
264    osg::ref_ptr<osg::Vec3Array> annotVertices = new osg::Vec3Array;
265
266    //Border
267    annotVertices->push_back( osg::Vec3(0.0f,0.0f,0.0f) * matrix  );
268    annotVertices->push_back( osg::Vec3(0.0f,arOffset,0.0f) * matrix  );
269
270    annotVertices->push_back( osg::Vec3(0.0f,arOffset,0.0f) * matrix  );
271    annotVertices->push_back( osg::Vec3(_width,arOffset,0.0f) * matrix  );
272
273    annotVertices->push_back( osg::Vec3(_width,arOffset,0.0f) * matrix  );
274    annotVertices->push_back( osg::Vec3(_width,0.0f,0.0f) * matrix  );
275
276    annotVertices->push_back( osg::Vec3(_width,0.0f,0.0f) * matrix  );
277    annotVertices->push_back( osg::Vec3(0.0f,0.0f,0.0f) * matrix  );
278
279    //Sticks
280    for(i=0; i<_numLabels; ++i)
281    {
282        const osg::Vec3 p1(osg::Vec3((i*labelxIncr), arOffset, 0.0f)*matrix);
283        const osg::Vec3 p2(osg::Vec3((i*labelxIncr), labely, 0.0f)*matrix);
284        annotVertices->push_back( p1 );
285        annotVertices->push_back( p2 );
286    }
287
288    osg::ref_ptr<osg::Geometry> annotationGeom = new osg::Geometry();
289    annotationGeom->addPrimitiveSet( new osg::DrawArrays(GL_LINES,0,annotVertices->size()) );
290    annotationGeom->setVertexArray( annotVertices.get() );
291    osg::ref_ptr<osg::Material> annotMaterial = new osg::Material;
292    annotMaterial->setDiffuse( osg::Material::FRONT, _textProperties._color );
293    annotationGeom->getOrCreateStateSet()->setAttribute( annotMaterial.get() );
294
295    addDrawable( annotationGeom.get() );
296}
Note: See TracBrowser for help on using the browser.