root/OpenSceneGraph/trunk/src/osgAnimation/StatsHandler.cpp @ 10764

Revision 10764, 24.4 kB (checked in by robert, 5 years ago)

<iterator>, <stdlib.h> and <ctype.h> includes required for QNX compiler

RevLine 
[10344]1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <sstream>
15#include <iomanip>
16#include <stdio.h>
[10352]17#include <math.h>
[10764]18#include <stdlib.h>
[10344]19
20#include <osg/io_utils>
21#include <osg/NodeVisitor>
22
23#include <osg/MatrixTransform>
24#include <osgViewer/Renderer>
25#include <osgAnimation/StatsHandler>
26#include <osgAnimation/EaseMotion>
27#include <osgAnimation/StatsVisitor>
28#include <osgViewer/ViewerEventHandlers>
29#include <osgViewer/Renderer>
30#include <osgAnimation/TimelineAnimationManager>
31
32#include <osg/PolygonMode>
33#include <osg/Geometry>
34#include <iostream>
35#include <cstdlib>
36
37static unsigned int getRandomValueinRange(unsigned int v)
38{
39    return static_cast<unsigned int>((rand() * 1.0 * v)/(RAND_MAX-1));
40}
41
42
43namespace osgAnimation
44{
45
46
47osg::Geometry* createBackgroundRectangle(const osg::Vec3& pos, const float width, const float height, osg::Vec4& color)
48{
49    osg::StateSet *ss = new osg::StateSet;
50    osg::Geometry* geometry = new osg::Geometry;
51
52    geometry->setUseDisplayList(false);
53    geometry->setStateSet(ss);
54
55    osg::Vec3Array* vertices = new osg::Vec3Array;
56    geometry->setVertexArray(vertices);
57
58    vertices->push_back(osg::Vec3(pos.x(), pos.y(), 0));
59    vertices->push_back(osg::Vec3(pos.x(), pos.y()-height,0));
60    vertices->push_back(osg::Vec3(pos.x()+width, pos.y()-height,0));
61    vertices->push_back(osg::Vec3(pos.x()+width, pos.y(),0));
62
63    osg::Vec4Array* colors = new osg::Vec4Array;
64    colors->push_back(color);
65    geometry->setColorArray(colors);
66    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
67
68    osg::DrawElementsUInt *base =  new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS,0);
69    base->push_back(0);
70    base->push_back(1);
71    base->push_back(2);
72    base->push_back(3);
73
74    geometry->addPrimitiveSet(base);
75
76    return geometry;
77}
78
79struct StatsGraph : public osg::MatrixTransform
80{
81    StatsGraph(osg::Vec3 pos, float width, float height)
82        : _pos(pos), _width(width), _height(height),
83          _statsGraphGeode(new osg::Geode)
84    {
85        _pos = pos - osg::Vec3(0, _height, 0.1);
86        setMatrix(osg::Matrix::translate(_pos));
87        setDataVariance(osg::Object::DYNAMIC);
88        addChild(_statsGraphGeode.get());
89        _statsGraphGeode->setCullingActive(false);
90    }
91   
92    void changeYposition(float y)
93    {
94        osg::Vec3 _pos = getMatrix().getTrans();
95        _pos[1] = y - _height;
96        setMatrix(osg::Matrix::translate(_pos));
97    }
98
99    void addStatGraph(osg::Stats* viewerStats, osg::Stats* stats, const osg::Vec4& color, float max, const std::string& nameBegin, const std::string& nameEnd = "")
100    {
101        _statsGraphGeode->addDrawable(new Graph(_width, _height, viewerStats, stats, color, max, nameBegin, nameEnd));
102    }
103
104    osg::Vec3           _pos;
105    float               _width;
106    float               _height;
107
108    osg::ref_ptr<osg::Geode> _statsGraphGeode;
109
110    struct NeverCull : public osg::Drawable::CullCallback
111    {
112        NeverCull() {}
113        bool cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const { return false;}
114    };
115
116
117    struct Graph : public osg::Geometry
118    {
119        Graph(float width, float height, osg::Stats* viewerStats, osg::Stats* stats,
120              const osg::Vec4& color, float max, const std::string& nameBegin, const std::string& nameEnd = "")
121        {
122            setDataVariance(osg::Object::DYNAMIC);
123            setUseDisplayList(false);
124
125            setVertexArray(new osg::Vec3Array);
126            getVertexArray()->setDataVariance(osg::Object::DYNAMIC);
127            setColor(color);
128
129            setUpdateCallback(new GraphUpdateCallback(width, height, viewerStats, stats, max, nameBegin, nameEnd));
130            setCullCallback(new NeverCull);
131        }
132
133        void setColor(const osg::Vec4& color) {
134            osg::Vec4Array* colors = new osg::Vec4Array;
135            colors->push_back(color);
136            setColorArray(colors);
137            setColorBinding(osg::Geometry::BIND_OVERALL);
138        }
139    };
140
141
142    struct GraphUpdateCallback : public osg::Drawable::UpdateCallback
143    {
144
145        const unsigned int      _width;
146        const unsigned int      _height;
147        mutable unsigned int    _curX;
148        osg::Stats*             _viewerStats;
149        osg::Stats*             _stats;
150        const float             _max;
151        const std::string       _nameBegin;
152        const std::string       _nameEnd;
153        mutable int              _frameNumber;
154
155        GraphUpdateCallback(float width, float height, osg::Stats* viewerStats, osg::Stats* stats,
156                            float max, const std::string& nameBegin, const std::string& nameEnd = "")
157            : _width((unsigned int)width), _height((unsigned int)height), _curX(0),
158              _viewerStats(viewerStats), _stats(stats), _max(max), _nameBegin(nameBegin), _nameEnd(nameEnd), _frameNumber(0)
159        {
160        }
161        virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
162        {
163            if (nv->getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR)
164                return;
165
166            osg::Geometry* geometry = const_cast<osg::Geometry*>(drawable->asGeometry());
167            if (!geometry) return;
168            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
169            if (!vertices) return;
170
171            int frameNumber = nv->getFrameStamp()->getFrameNumber();
172            if (frameNumber == _frameNumber)
173                return;
174
175
176            // Get stats
177            double value;
178            if (_nameEnd.empty())
179            {
180                if (!_stats->getAttribute(_stats->getLatestFrameNumber(), _nameBegin, value ))
181                {
182                    value = 0.0;
183                }
184            }
185            else
186            {
187                double beginValue, endValue;
188                if (_stats->getAttribute( frameNumber, _nameBegin, beginValue) &&
189                    _stats->getAttribute( frameNumber, _nameEnd, endValue) )
190                {
191                    value = endValue - beginValue;
192                }
193                else
194                {
195                    value = 0.0;
196                }
197            }
198            // Add new vertex for this frame.
199            value = osg::clampTo(value, 0.0, double(_max));
200
201            if (!vertices->size()) {
202                for (int i = 0; i < (int)_width; i++)
203                    vertices->push_back(osg::Vec3(float(_curX++), 0, 0));
204                // Create primitive set if none exists.
205                if (geometry->getNumPrimitiveSets() == 0)
206                    geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, 0));
207                osg::DrawArrays* drawArrays = dynamic_cast<osg::DrawArrays*>(geometry->getPrimitiveSet(0));
208                drawArrays->setFirst(0);
209                drawArrays->setCount(vertices->size());
210            }
211            vertices->push_back(osg::Vec3(float(_curX), float(_height) / _max * value, 0));
212
213            unsigned int excedent = vertices->size() - _width;
214            vertices->erase(vertices->begin(), vertices->begin() + excedent);
215
216            // Make the graph scroll when there is enough data.
217            // Note: We check the frame number so that even if we have
218            // many graphs, the transform is translated only once per
219            // frame.
220            static const float increment = -1.0;
221            if (_frameNumber != frameNumber)
222            {
223                // We know the exact layout of this part of the scene
224                // graph, so this is OK...
225                osg::MatrixTransform* transform =
226                    geometry->getParent(0)->getParent(0)->asTransform()->asMatrixTransform();
227                if (transform)
228                {
229                    transform->setMatrix(transform->getMatrix() * osg::Matrix::translate(osg::Vec3(increment, 0, 0)));
230                }
231            }
232
233            _curX++;
234            _frameNumber = frameNumber;
235
236            geometry->dirtyBound();
237        }
238    };
239};
240
241// Drawcallback to draw averaged attribute
242struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback
243{
244    ValueTextDrawCallback(osg::Stats* stats, const std::string& name):
245        _stats(stats),
246        _attributeName(name),
247        _frameNumber(0)
248    {
249    }
250
251    /** do customized draw code.*/
252    virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const
253    {
254        osgText::Text* text = (osgText::Text*)drawable;
255
256        int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber();
257        if (frameNumber == _frameNumber) {
258            text->drawImplementation(renderInfo);
259            return;
260        }
261
262        double value;
263        if (_stats->getAttribute(_stats->getLatestFrameNumber(), _attributeName, value))
264        {
265            sprintf(_tmpText,"%4.2f",value);
266            text->setText(_tmpText);
267        }
268        else
269        {
270            text->setText("");
271        }
272        _frameNumber = frameNumber;
273        text->drawImplementation(renderInfo);
274    }
275
276    osg::ref_ptr<osg::Stats>    _stats;
277    std::string                 _attributeName;
278    mutable char                _tmpText[128];
279    mutable int                 _frameNumber;
280};
281
282
283
284
285
286    struct StatAction
287    {
288        double _lastTime;
289        std::string _name;
290        osg::ref_ptr<osg::Group> _group;
291        osg::ref_ptr<osg::Geode> _label;
292        osg::ref_ptr<osg::MatrixTransform> _graph;
293        osg::ref_ptr<osgText::Text> _textLabel;
294        osgAnimation::OutCubicMotion _fade;
295
296        StatAction() { _lastTime = 0; _fade = osgAnimation::OutCubicMotion(0,5); }
297        void init(osg::Stats* stats, const std::string& name, const osg::Vec3& pos, float width, float heigh, const osg::Vec4& color);
298        void setPosition(const osg::Vec3& pos);
299#if 0
300        void touch()
301        {
302            _lastTime = osg::Timer::instance()->time_s();
303            float a = 1.0 - _fade.getValueAt(0.0);
304            setAlpha(a);
305        }
306        bool update() {
307            double t = osg::Timer::instance()->time_s();
308            float alpha = 1.0 - _fade.getValueAt(t-_lastTime);
309            if (t - _lastTime > _fade.getDuration())
310                return true;
311            setAlpha(alpha);
312            return false;
313        }
314#endif
315        void setAlpha(float v);
316    };
317
318
319    struct StatsTimeline : public osg::NodeCallback
320    {
321        static float _statsHeight;
322        static float _statsWidth;
323
324        osg::ref_ptr<osg::Geometry> _background;
325        osg::ref_ptr<osgAnimation::Timeline> _timeline;
326        osg::ref_ptr<osg::MatrixTransform> _group;
327        std::map<std::string, StatAction > _actions;
328
329        StatsTimeline()
330        {
331            _statsHeight = 1024;
332            _statsWidth = 1280;
333        }
334        osg::MatrixTransform* createStatsForTimeline(osgAnimation::Timeline* timeline)
335        {
336            _timeline = timeline;
337
338            std::string font("fonts/arial.ttf");
339
340            float leftPos = 10.0f;
341            float startBlocks = 150.0f;
342            float characterSize = 20.0f;
343
344
345            osg::Vec4 backgroundColor(0.0, 0.0, 0.0f, 0.3);
346            float backgroundMargin = 5;
[10347]347            //float backgroundSpacing = 3;
[10344]348
349            osg::Vec4 color(1.0, 1.0, 1.0, 1.0);
350
351            _group = new osg::MatrixTransform;
352            _group->setDataVariance(osg::Object::DYNAMIC);
353
354            {
355                osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f);
[10347]356                //float topOfViewerStats = pos.y() + characterSize;
[10344]357                osg::ref_ptr<osg::Stats> stats = _timeline->getStats();
358                pos.y() -= characterSize + backgroundMargin;
359
360                {
361                    osg::Geode* geode = new osg::Geode();
362                    _group->addChild(geode);
363                    osg::ref_ptr<osgText::Text> timeLabel = new osgText::Text;
364                    geode->addDrawable( timeLabel.get() );
365               
366                    timeLabel->setColor(color);
367                    timeLabel->setFont(font);
368                    timeLabel->setCharacterSize(characterSize);
369                    timeLabel->setPosition(pos);
370                    timeLabel->setText("Time: ");
371
372                    osg::ref_ptr<osgText::Text> timeLabelValue = new osgText::Text;
373                    geode->addDrawable( timeLabelValue.get() );
374
375                    timeLabelValue->setColor(color);
376                    timeLabelValue->setFont(font);
377                    timeLabelValue->setCharacterSize(characterSize);
378                    timeLabelValue->setPosition(pos + osg::Vec3(startBlocks, 0,0));
379                    timeLabelValue->setText("0.0");
380
[10351]381                    timeLabelValue->setDrawCallback(new ValueTextDrawCallback(stats.get(),"Timeline"));
[10344]382                }
383            }
384            {
385                osg::Vec3 pos(leftPos, _statsHeight - 24.0f ,0.0f);
[10347]386                //float topOfViewerStats = pos.y();
[10344]387                osg::Geode* geode = new osg::Geode;
388                _background = createBackgroundRectangle(
389                    pos + osg::Vec3(-backgroundMargin, backgroundMargin, 0),
390                    _statsWidth - 2 * backgroundMargin,
391                    (3 + 4.5 * 1) * characterSize + 2 * backgroundMargin,
392                    backgroundColor);
[10351]393                geode->addDrawable(_background.get());
[10344]394                _group->addChild(geode);
395            }
396
[10351]397            return _group.get();
[10344]398        }
399
400        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
401        {
402            if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) {
403                updateGraph();
404            }
405            traverse(node,nv);
406        }
407
408        void updateGraph()
409        {
410            osgAnimation::StatsActionVisitor* visitor = _timeline->getStatsVisitor();
411            if (!visitor)
412                return;
413
414            std::string font("fonts/arial.ttf");
415            float leftPos = 10.0f;
416            float characterSize = 20.0f;
417
418            float backgroundMargin = 5;
[10347]419            //float backgroundSpacing = 3;
[10344]420            float graphSpacing = 5;
421
422            float width = _statsWidth - 4 * backgroundMargin;
423            float height = characterSize;
424            osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f);
425            pos.y() -= characterSize *2 + backgroundMargin;
426
427             for (std::map<std::string, StatAction >::iterator it = _actions.begin(); it != _actions.end(); it++) {
[10701]428                 (*it).second._group->setNodeMask(~osg::Node::NodeMask(1));
[10344]429             }
430
431            const std::vector<std::string>& channels = visitor->getChannels();
432            std::map<std::string,int> size;
433            for (int i = 0; i < (int)channels.size(); i++) {
434                std::string name = channels[i];
435                if (_actions.find(name) == _actions.end()) {
436                    osg::Vec4 color(getRandomValueinRange(255)/255.0, getRandomValueinRange(255)/255.0, getRandomValueinRange(255)/255.0, 1.0);
437                    _actions[name].init(visitor->getStats(), name, pos, width, height, color);
[10351]438                    _group->addChild(_actions[name]._group.get());
[10344]439                    //_actions[name].touch();
440                } else {
441                    _actions[name].setPosition(pos);
442                    //_actions[name].touch();
443                }
[10764]444                _actions[name]._group->setNodeMask(~osg::Node::NodeMask(0x0));
[10344]445                size[name] = 0;
446                pos.y() -= characterSize + graphSpacing;
447            }
448
449            pos.y() -= backgroundMargin;
450            osg::Vec3Array* array = dynamic_cast<osg::Vec3Array*>(_background->getVertexArray());
451            float y = (*array)[0][1];
452            y = y - (pos.y() + backgroundMargin); //(2 * backgroundMargin + (size.size() * (characterSize + graphSpacing)));
453            (*array)[1][1] = pos.y();
454            (*array)[2][1] = pos.y();
455            array->dirty();
456            _background->dirtyBound();
457        }
458    };
459    float StatsTimeline::_statsHeight;
460    float StatsTimeline::_statsWidth;
461
462
463
464struct FindTimelineStats : public osg::NodeVisitor
465{
466    std::vector<osg::ref_ptr<osgAnimation::Timeline> > _timelines;
467
468    FindTimelineStats() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
469
470    void apply(osg::Node& node) {
471        osg::NodeCallback* cb = node.getUpdateCallback();
472        while (cb) {
473            osgAnimation::TimelineAnimationManager* tam = dynamic_cast<osgAnimation::TimelineAnimationManager*>(cb);
474            if (tam)
475                _timelines.push_back(tam->getTimeline());
476            cb = cb->getNestedCallback();
477        }
478        traverse(node);
479    }
480};
481
482
483StatsHandler::StatsHandler():
484    _keyEventTogglesOnScreenStats('a'),
485    _keyEventPrintsOutStats('A'),
486    _statsType(NO_STATS),
487    _initialized(false),
488    _statsWidth(1280.0f),
489    _statsHeight(1024.0f)
490{
491    _camera = new osg::Camera;
492    _camera->setRenderer(new osgViewer::Renderer(_camera.get()));
493    _camera->setProjectionResizePolicy(osg::Camera::FIXED);
494}
495
496bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
497{
498    osgViewer::View* myview = dynamic_cast<osgViewer::View*>(&aa);
499    if (!myview) return false;
500
501    osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(myview->getViewerBase());
502
503    if (!viewer->getSceneData())
504        return false;
505    if (ea.getHandled()) return false;
506
507    switch(ea.getEventType())
508    {
509        case(osgGA::GUIEventAdapter::KEYDOWN):
510        {
511            if (ea.getKey()==_keyEventTogglesOnScreenStats)
512            {
513                if (viewer->getViewerStats())
514                {
515
516                    if (!_switch.get()) {
517                        FindTimelineStats finder;
518                        viewer->getSceneData()->accept(finder);
519                        if (finder._timelines.empty())
520                            return false;
521                    }
522
523                    if (!_initialized)
524                    {
525                        setUpHUDCamera(viewer);
526                        setUpScene(dynamic_cast<osgViewer::Viewer*>(viewer));
527                    }
528
529                    ++_statsType;
530
531                    if (_statsType==LAST) _statsType = NO_STATS;
532
533
534                    switch(_statsType)
535                    {
536                        case(NO_STATS):
537                        {
538                            _camera->setNodeMask(0x0);
539                            _switch->setAllChildrenOff();
540                            break;
541                        }
542                        case(FRAME_RATE):
543                        {
544                            _camera->setNodeMask(0xffffffff);
545                            _switch->setAllChildrenOn();
546                            break;
547                        }
548                        default:
549                            break;
550                    }
551
552
553                }
554                return true;
555            }
556            if (ea.getKey()==_keyEventPrintsOutStats)
557            {
558                FindTimelineStats finder;
559                viewer->getSceneData()->accept(finder);
560                if (!finder._timelines.empty()) {
561                    osg::notify(osg::NOTICE)<<std::endl<<"Stats report:"<<std::endl;
562                    typedef std::vector<osg::Stats*> StatsList;
563                    StatsList statsList;
564
565                    for (int i = 0; i < (int)finder._timelines.size(); i++)
[10656]566                        statsList.push_back(finder._timelines[i]->getStats());
[10344]567
568                    for(int i = statsList[0]->getEarliestFrameNumber(); i<= statsList[0]->getLatestFrameNumber()-1; ++i)
569                    {
570                        for(StatsList::iterator itr = statsList.begin();
571                            itr != statsList.end();
572                            ++itr)
573                        {
574                            if (itr==statsList.begin()) (*itr)->report(osg::notify(osg::NOTICE), i);
575                            else (*itr)->report(osg::notify(osg::NOTICE), i, "    ");
576                        }
577                        osg::notify(osg::NOTICE)<<std::endl;
578                    }
579
580                }
581                return true;
582            }
583        }
584        default: break;
585    }
586
587    return false;
588
589}
590
591void StatsHandler::reset()
592{
593    _initialized = false;
594    _camera->setGraphicsContext(0);
595    _camera->removeChildren( 0, _camera->getNumChildren() );
596}
597
598void StatsHandler::setUpHUDCamera(osgViewer::ViewerBase* viewer)
599{
600    osgViewer::GraphicsWindow* window = dynamic_cast<osgViewer::GraphicsWindow*>(_camera->getGraphicsContext());
601
602    if (!window)
603    {
604        osgViewer::Viewer::Windows windows;
605        viewer->getWindows(windows);
606
607        if (windows.empty()) return;
608
609        window = windows.front();
610    }
611
612    _camera->setGraphicsContext(window);
613
614    _camera->setViewport(0, 0, window->getTraits()->width, window->getTraits()->height);
615   
616    _camera->setRenderOrder(osg::Camera::POST_RENDER, 10);
617
618    _camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0,_statsWidth,0.0,_statsHeight));
619    _camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
620    _camera->setViewMatrix(osg::Matrix::identity());
621
622    // only clear the depth buffer
623    _camera->setClearMask(0); //GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //-1);
624    _camera->setAllowEventFocus(false);
625    _camera->setCullMask(0x1);
626    osgViewer::Viewer* v = dynamic_cast<osgViewer::Viewer*>(viewer);
[10351]627    v->getSceneData()->asGroup()->addChild(_camera.get());
[10344]628    _initialized = true;
629}
630
631void StatsHandler::setUpScene(osgViewer::Viewer* viewer)
632{
633    if (!viewer->getSceneData())
634        return;
635
636    FindTimelineStats finder;
637    viewer->getSceneData()->accept(finder);
638    if (finder._timelines.empty())
639        return;
640
641    _switch = new osg::Switch;
642    osg::StateSet* stateset = _switch->getOrCreateStateSet();
643    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
644    stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
645    stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
646    stateset->setAttribute(new osg::PolygonMode(), osg::StateAttribute::PROTECTED);
647
648    _group = new osg::Group;
649    _camera->addChild(_switch.get());
[10351]650    _switch->addChild(_group.get());
[10344]651   
652    for (int i = 0; i < (int)finder._timelines.size(); i++) {
653        StatsTimeline* s = new StatsTimeline;
[10351]654        osg::MatrixTransform* m = s->createStatsForTimeline(finder._timelines[i].get());
[10344]655        m->setUpdateCallback(s);
[10656]656        m->setMatrix(osg::Matrix::translate(0, -i * 100, 0));
[10344]657        _group->addChild(m);
658    }
659}
660
661
662
663
664void StatAction::init(osg::Stats* stats, const std::string& name, const osg::Vec3& pos, float width, float height, const osg::Vec4& color)
665{
666    std::string font("fonts/arial.ttf");
667    float characterSize = 20.0f;
668    float startBlocks = 150.0f;
669
670    _name = name;
671    _group = new osg::Group;
672
673    _label = new osg::Geode;
674    _textLabel = new osgText::Text;
[10351]675    _label->addDrawable(_textLabel.get());
[10344]676    _textLabel->setDataVariance(osg::Object::DYNAMIC);
677    _textLabel->setColor(color);
678    _textLabel->setFont(font);
679    _textLabel->setCharacterSize(characterSize);
680    _textLabel->setPosition(pos - osg::Vec3(0, height, 0));
681    _textLabel->setText(name);
682
683    StatsGraph* graph = new StatsGraph(pos + osg::Vec3(startBlocks, 0,0) , width-startBlocks, height);
684    graph->setCullingActive(false);
685    graph->addStatGraph(stats, stats, color, 1.0, name);
686    _graph = graph;
687   
[10351]688    _group->addChild(_label.get());
689    _group->addChild(_graph.get());
[10344]690}
691void StatAction::setAlpha(float v)
692{
693    std::cout << this << " color alpha " << v << std::endl;
694    StatsGraph* gfx = dynamic_cast<StatsGraph*>(_graph.get());
695    osg::Vec4 color = _textLabel->getColor();
696    color[3] = v;
697    _textLabel->setColor(color);
698    for (int i = 0; i < (int) gfx->_statsGraphGeode->getNumDrawables(); i++) {
699        StatsGraph::Graph* g = dynamic_cast<StatsGraph::Graph*>(gfx->_statsGraphGeode->getDrawable(0));
700        g->setColor(color);
701    }
702}
703
704void StatAction::setPosition(const osg::Vec3& pos)
705{
706    float characterSize = 20.0f;
707    StatsGraph* gfx = dynamic_cast<StatsGraph*>(_graph.get());
708    gfx->changeYposition(pos[1]);
709    _textLabel->setPosition(pos - osg::Vec3(0, characterSize,0));
710
711   
712
713}
714
715
716void StatsHandler::getUsage(osg::ApplicationUsage& usage) const
717{
718    usage.addKeyboardMouseBinding("s","On screen stats.");
719    usage.addKeyboardMouseBinding("S","Output stats to console.");
720}
721
722}
Note: See TracBrowser for help on using the browser.