~ubuntu-branches/debian/experimental/openscenegraph/experimental

« back to all changes in this revision

Viewing changes to OpenSceneGraph/src/osgAnimation/StatsHandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Luaces
  • Date: 2010-05-03 21:42:01 UTC
  • mfrom: (1.1.9 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100503214201-iy060qxb94vsfv87
Tags: 2.8.3-3
* Added README.source. Thanks Manuel Montecelo.
* Removed FindGDAL.cmake file supplied by upstream since it does not
  detect current libgdal1-1.6.0. The script provided by CMake works
  fine.
* Removed openthreads-doc since OpenThreads documentation is shared with
  OpenSceneGraph's, hence this package was empty.
* Now ccache handling is being done automatically by CMake.
* Drop conflict dependencies with previous versions to let them coexist
  with current ones (Closes: #580079 #580081).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
17
#include <math.h>
 
18
#include <stdlib.h>
 
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
 
 
37
static unsigned int getRandomValueinRange(unsigned int v)
 
38
{
 
39
    return static_cast<unsigned int>((rand() * 1.0 * v)/(RAND_MAX-1));
 
40
}
 
41
 
 
42
 
 
43
namespace osgAnimation
 
44
{
 
45
 
 
46
 
 
47
osg::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
 
 
79
struct 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
 
242
struct 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;
 
347
            //float backgroundSpacing = 3;
 
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);
 
356
                //float topOfViewerStats = pos.y() + characterSize;
 
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
 
 
381
                    timeLabelValue->setDrawCallback(new ValueTextDrawCallback(stats.get(),"Timeline"));
 
382
                }
 
383
            }
 
384
            {
 
385
                osg::Vec3 pos(leftPos, _statsHeight - 24.0f ,0.0f);
 
386
                //float topOfViewerStats = pos.y();
 
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);
 
393
                geode->addDrawable(_background.get());
 
394
                _group->addChild(geode);
 
395
            }
 
396
 
 
397
            return _group.get();
 
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;
 
419
            //float backgroundSpacing = 3;
 
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) {
 
428
                 (*it).second._group->setNodeMask(~osg::Node::NodeMask(1));
 
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);
 
438
                    _group->addChild(_actions[name]._group.get());
 
439
                    //_actions[name].touch();
 
440
                } else {
 
441
                    _actions[name].setPosition(pos);
 
442
                    //_actions[name].touch();
 
443
                }
 
444
                _actions[name]._group->setNodeMask(~osg::Node::NodeMask(0x0));
 
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
 
 
464
struct 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
 
 
483
StatsHandler::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
 
 
496
bool 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++)
 
566
                        statsList.push_back(finder._timelines[i]->getStats());
 
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
 
 
591
void StatsHandler::reset()
 
592
{
 
593
    _initialized = false;
 
594
    _camera->setGraphicsContext(0);
 
595
    _camera->removeChildren( 0, _camera->getNumChildren() );
 
596
}
 
597
 
 
598
void 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);
 
627
    v->getSceneData()->asGroup()->addChild(_camera.get());
 
628
    _initialized = true;
 
629
}
 
630
 
 
631
void 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());
 
650
    _switch->addChild(_group.get());
 
651
    
 
652
    for (int i = 0; i < (int)finder._timelines.size(); i++) {
 
653
        StatsTimeline* s = new StatsTimeline;
 
654
        osg::MatrixTransform* m = s->createStatsForTimeline(finder._timelines[i].get());
 
655
        m->setUpdateCallback(s);
 
656
        m->setMatrix(osg::Matrix::translate(0, -i * 100, 0));
 
657
        _group->addChild(m);
 
658
    }
 
659
}
 
660
 
 
661
 
 
662
 
 
663
 
 
664
void 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;
 
675
    _label->addDrawable(_textLabel.get());
 
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
    
 
688
    _group->addChild(_label.get());
 
689
    _group->addChild(_graph.get());
 
690
}
 
691
void 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
 
 
704
void 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
 
 
716
void 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
}