root/OpenSceneGraph/trunk/examples/osgsequence/osgsequence.cpp @ 5954

Revision 5954, 6.8 kB (checked in by robert, 8 years ago)

Ported following examples to osgViewer:

osgparticleeffects
osgphotoalbum
osgpick
osgpoints
osgpointsprite
osgprecipitation
osgprerender
osgprerendercubemap
osgreflect
osgscalarbar
osgscribe
osgsequence
osgplanets

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3/*
4 * This application is open source and may be redistributed and/or modified   
5 * freely and without restriction, both in commericial and non commericial
6 * applications,as long as this copyright notice is maintained.
7 *
8 * This application 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.
11*/
12
13#include <osgText/Text>
14#include <osg/Geode>
15#include <osg/Group>
16#include <osg/Projection>
17#include <osg/Sequence>
18#include <osg/MatrixTransform>
19
20#include <osgDB/ReadFile>
21
22#include <osgViewer/Viewer>
23
24#include <iostream>
25
26// create text drawable at 'pos'
27osg::Geode* createText(const std::string& str, const osg::Vec3& pos)
28{
29    // text drawable
30    osgText::Text* text = new osgText::Text;
31    text->setFont(std::string("fonts/arial.ttf"));
32    text->setPosition(pos);
33    text->setText(str);
34
35    // geode
36    osg::Geode* geode = new osg::Geode;
37    geode->addDrawable(text);
38
39    return geode;
40}
41
42osg::Node* createTextGroup(const char** text)
43{
44    osg::Group* group = new osg::Group;
45
46    osg::Vec3 pos(120.0f, 800.0f, 0.0f);
47    const osg::Vec3 delta(0.0f, -60.0f, 0.0f);
48
49    // header
50    const char** t = text;
51    group->addChild(createText(*t++, pos));
52    pos += delta;
53
54    // remainder of text under sequence
55    osg::Sequence* seq = new osg::Sequence;
56    group->addChild(seq);
57    while (*t) {
58        seq->addChild(createText(*t++, pos));
59        seq->setTime(seq->getNumChildren()-1, 2.0f);
60        pos += delta;
61    }
62
63    // loop through all children
64    seq->setInterval(osg::Sequence::LOOP, 0,-1);
65
66    // real-time playback, repeat indefinitively
67    seq->setDuration(1.0f, -1);
68
69    // must be started explicitly
70    seq->setMode(osg::Sequence::START);
71
72    return group;
73}
74
75osg::Node* createHUD(osg::Node* node)
76{
77    // absolute transform
78    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
79    modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
80    modelview_abs->setMatrix(osg::Matrix::identity());
81    modelview_abs->addChild(node);
82
83    // 2D projection node
84    osg::Projection* projection = new osg::Projection;
85    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
86    projection->addChild(modelview_abs);
87
88    // turn off lighting and depth test
89    osg::StateSet* state = modelview_abs->getOrCreateStateSet();
90    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
91    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
92
93    return projection;
94}
95
96osg::Node* createScaledNode(osg::Node* node, float targetScale)
97{
98    // create scale matrix
99    osg::MatrixTransform* transform = new osg::MatrixTransform;
100
101    const osg::BoundingSphere& bsphere = node->getBound();
102    float scale = targetScale / bsphere._radius;
103    transform->setMatrix(osg::Matrix::scale(scale,scale,scale));
104    transform->setDataVariance(osg::Object::STATIC);
105    transform->addChild(node);
106
107    // rescale normals
108    osg::StateSet* state = transform->getOrCreateStateSet();
109    state->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
110
111    return transform;
112}
113
114osg::Sequence* createSequence(osg::ArgumentParser& arguments)
115{
116    // assumes any remaining parameters are models
117    osg::Sequence* seq = new osg::Sequence;
118    for (int i = 1; i < arguments.argc(); ++i)
119    {
120        // load model
121        osg::Node* node = osgDB::readNodeFile(arguments[i]);
122        if (!node) {
123            continue;
124        }
125        seq->addChild(createScaledNode(node, 100.0f));
126        seq->setTime(seq->getNumChildren()-1, 1.0f);
127    }
128
129    // loop through all children
130    seq->setInterval(osg::Sequence::LOOP, 0,-1);
131
132    // real-time playback, repeat indefinitively
133    seq->setDuration(1.0f, -1);
134
135    seq->setMode(osg::Sequence::START);
136
137    return seq;
138}
139
140// event handler to control sequence
141class SequenceEventHandler : public osgGA::GUIEventHandler
142{
143public:
144    SequenceEventHandler(osg::Sequence* seq)
145    {
146        _seq = seq;
147    }
148
149    // handle keydown events
150    virtual bool handle(const osgGA::GUIEventAdapter& ea,
151                        osgGA::GUIActionAdapter&)
152    {
153        if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
154            switch (ea.getKey()) {
155            case 's':
156                {
157                    osg::Sequence::SequenceMode mode = _seq->getMode();
158                    if (mode == osg::Sequence::STOP) {
159                        mode = osg::Sequence::START;
160                        std::cerr << "Start" << std::endl;
161                    }
162                    else if (mode == osg::Sequence::PAUSE) {
163                        mode = osg::Sequence::RESUME;
164                        std::cerr << "Resume" << std::endl;
165                    }
166                    else {
167                        mode = osg::Sequence::PAUSE;
168                        std::cerr << "Pause" << std::endl;
169                    }
170                    _seq->setMode(mode);
171                }
172                break;
173            case 'l':
174                {
175                    osg::Sequence::LoopMode mode;
176                    int begin, end;
177                    _seq->getInterval(mode, begin, end);
178                    if (mode == osg::Sequence::LOOP) {
179                        mode = osg::Sequence::SWING;
180                        std::cerr << "Swing" << std::endl;
181                    }
182                    else {
183                        mode = osg::Sequence::LOOP;
184                        std::cerr << "Loop" << std::endl;
185                    }
186                    _seq->setInterval(mode, begin, end);
187                }
188                break;
189            default:
190                break;
191            }
192        }
193
194        return false;
195    }
196
197private:
198    osg::ref_ptr<osg::Sequence> _seq;
199};
200
201
202int main( int argc, char **argv )
203{
204    // use an ArgumentParser object to manage the program arguments.
205    osg::ArgumentParser arguments(&argc,argv);
206   
207    // construct the viewer.
208    osgViewer::Viewer viewer;
209    // root
210    osg::Group* rootNode = new osg::Group;
211
212    // create info display
213    const char* text[] = {
214        "osg::Sequence Mini-Howto",
215        "- can be used for simple flip-book-style animation",
216        "- is subclassed from osg::Switch",
217        "- assigns a display duration to each child",
218        "- can loop or swing through an interval of it's children",
219        "- can repeat the interval a number of times or indefinitively",
220        "- press 's' to start/pause/resume",
221        "- press 'l' to toggle loop/swing mode",
222        NULL
223    };
224    rootNode->addChild(createHUD(createTextGroup(text)));
225
226    // add sequence of models from command line
227    osg::Sequence* seq = createSequence(arguments);
228    rootNode->addChild(seq);
229
230    // add model to viewer.
231    viewer.setSceneData(rootNode);
232
233    // add event handler to control sequence
234    viewer.addEventHandler(new SequenceEventHandler(seq));
235
236    return viewer.run();
237}
Note: See TracBrowser for help on using the browser.