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

Revision 11009, 24.4 kB (checked in by robert, 4 years ago)

From Cedric Pinson, "Here a list of changes:
Bone now inherit from MatrixTransform?. It simplify a lot the update of
Bone matrix. It helps to have the bone system more generic. eg it's now
possible to have animation data with precomputed bind matrix. The other
benefit, is now the collada plugin will be able to use osgAnimation to
display skinned mesh. Michael Plating did a great work to improve this
aspect, he is working on the collada plugin and should be able to submit
a new version soon.
The RigGeometry? has been refactored so now it works when you save and
reload RigGeometry? because the source is not touched anymore. The
benefit with this update is that it should be now possible to use a
MorphGeometry? as source for a RigGeometry?.

The bad news is that the format has changed, so i have rebuild osg-data
related to osgAnimation data, updated the blender exporter to export to
the new format.
The fbx plugin could be touched about this commit, i dont compile it so
i can't give more information about it.
The bvh plugin has been updated by Wang rui so this one is fixed with
the new code of osgAnimation.
The examples has been updated to work with the new code too...

The example osg-data/example.osg should be remove, it's an old example
that does not work.

For people using blender the blender exporter up to date is here:
http://hg.plopbyte.net/osgexport2/
it will be merge to http://hg.plopbyte.net/osgexport/ as soon as the
modification will be push in the trunk.
"

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
[11009]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.