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

Revision 10701, 24.4 kB (checked in by cedricpinson, 4 years ago)

From Cedric Pinson, Fix warning in osgAnimation, UpdateCallback?. Fix bug removing callback in Action. Fix warning Stats

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