root/OpenSceneGraph/trunk/examples/osganimationeasemotion/osganimationeasemotion.cpp @ 14101

Revision 13576, 11.9 kB (checked in by robert, 17 hours ago)

Release OpenSceneGraph-3.3.3

  • Property svn:eol-style set to native
Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2010 Jeremy Moles <cubicool@gmail.com>
3 *
4 * This library is open source and may be redistributed and/or modified under
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
13 */
14
15#include <osg/Geode>
16#include <osg/MatrixTransform>
17#include <osg/ShapeDrawable>
18#include <osgGA/TrackballManipulator>
19#include <osgViewer/Viewer>
20#include <osgViewer/ViewerEventHandlers>
21#include <osgAnimation/EaseMotion>
22#include <osgWidget/WindowManager>
23#include <osgWidget/Box>
24#include <osgWidget/Table>
25#include <osgWidget/Label>
26
27class EaseMotionSampler;
28
29const unsigned int WINDOW_WIDTH  = 800;
30const unsigned int WINDOW_HEIGHT = 600;
31const unsigned int MASK_2D       = 0xF0000000;
32const unsigned int MASK_3D       = 0x0F000000;
33const float        M_START       = 0.0f;
34const float        M_DURATION    = 2.0f;
35const float        M_CHANGE      = 1.0f;
36
37EaseMotionSampler* EASE_MOTION_SAMPLER = 0;
38osg::Geode*        EASE_MOTION_GEODE   = 0;
39
40osg::Geometry* createEaseMotionGeometry(osgAnimation::Motion* motion) {
41    osg::Geometry*  geom = new osg::Geometry();
42    osg::Vec4Array* cols = new osg::Vec4Array();
43    osg::Vec3Array* v    = new osg::Vec3Array();
44
45    for(float i = 0.0f; i < M_DURATION; i += M_DURATION / 256.0f) v->push_back(
46        osg::Vec3(i * 30.0f, motion->getValueAt(i) * 30.0f, 0.0f)
47        );
48
49    cols->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
50
51    geom->setUseDisplayList(false);
52    geom->setVertexArray(v);
53    geom->setColorArray(cols, osg::Array::BIND_OVERALL);
54    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, v->size()));
55
56    return geom;
57}
58
59class EaseMotionSampler: public osg::NodeCallback
60{
61public:
62    float     _previous;
63    osg::Vec3 _pos;
64
65    osg::ref_ptr<osgAnimation::Motion> _motion;
66
67    EaseMotionSampler(const osg::Vec3& pos):
68        _previous (0.0f),
69        _pos      (pos) {
70    }
71
72    void operator()(osg::Node* node, osg::NodeVisitor* nv) {
73        if(!_motion.valid()) return;
74
75        osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(node);
76
77        if(!mt) return;
78
79        double t = nv->getFrameStamp()->getSimulationTime();
80
81        // This avoids a little glitch when the animation doesn't start right away
82        // when the application is launched.
83        if(_previous == 0.0f) _previous = t;
84
85        _motion->update(t - _previous);
86
87        _previous = t;
88
89        mt->setMatrix(osg::Matrix::translate(_pos * _motion->getValue()));
90    }
91
92    template<typename T>
93    void setMotion() {
94        _motion = new T(M_START, M_DURATION, M_CHANGE, osgAnimation::Motion::LOOP);
95
96        EASE_MOTION_GEODE->removeDrawables(0, EASE_MOTION_GEODE->getNumDrawables());
97        EASE_MOTION_GEODE->addDrawable(createEaseMotionGeometry(_motion.get()));
98    }
99};
100
101struct ColorLabel: public osgWidget::Label {
102    ColorLabel(const char* label):
103        osgWidget::Label(label, "") {
104        setFont("fonts/VeraMono.ttf");
105        setFontSize(14);
106        setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
107
108        setColor(0.3f, 0.3f, 0.3f, 1.0f);
109        setPadding(2.0f);
110        setCanFill(true);
111
112        addSize(150.0f, 25.0f);
113
114        setLabel(label);
115        setEventMask(osgWidget::EVENT_MOUSE_PUSH | osgWidget::EVENT_MASK_MOUSE_MOVE);
116    }
117
118    bool mousePush(double, double, const osgWidget::WindowManager*) {
119        osgWidget::Table* p = dynamic_cast<osgWidget::Table*>(_parent);
120
121        if(!p) return false;
122
123        p->hide();
124
125        const std::string& name = getName();
126
127        if(!name.compare("OutQuadMotion"))
128            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutQuadMotion>()
129                ;
130
131        else if(!name.compare("InQuadMotion"))
132            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InQuadMotion>()
133                ;
134
135        else if(!name.compare("InOutQuadMotion"))
136            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutQuadMotion>()
137                ;
138
139        else if(!name.compare("OutCubicMotion"))
140            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutCubicMotion>()
141                ;
142
143        else if(!name.compare("InCubicMotion"))
144            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InCubicMotion>()
145                ;
146
147        else if(!name.compare("InOutCubicMotion"))
148            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutCubicMotion>()
149                ;
150
151        else if(!name.compare("OutQuartMotion"))
152            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutQuartMotion>()
153                ;
154
155        else if(!name.compare("InQuartMotion"))
156            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InQuartMotion>()
157                ;
158
159        else if(!name.compare("InOutQuartMotion"))
160            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutQuartMotion>()
161                ;
162
163        else if(!name.compare("OutBounceMotion"))
164            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutBounceMotion>()
165                ;
166
167        else if(!name.compare("InBounceMotion"))
168            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InBounceMotion>()
169                ;
170
171        else if(!name.compare("InOutBounceMotion"))
172            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutBounceMotion>()
173                ;
174
175        else if(!name.compare("OutElasticMotion"))
176            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutElasticMotion>()
177                ;
178
179        else if(!name.compare("InElasticMotion"))
180            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InElasticMotion>()
181                ;
182
183        else if(!name.compare("InOutElasticMotion"))
184            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutElasticMotion>()
185                ;
186
187        else if(!name.compare("OutSineMotion"))
188            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutSineMotion>()
189                ;
190
191        else if(!name.compare("InSineMotion"))
192            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InSineMotion>()
193                ;
194
195        else if(!name.compare("InOutSineMotion"))
196            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutSineMotion>()
197                ;
198
199        else if(!name.compare("OutBackMotion"))
200            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutBackMotion>()
201                ;
202
203        else if(!name.compare("InBackMotion"))
204            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InBackMotion>()
205                ;
206
207        else if(!name.compare("InOutBackMotion"))
208            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutBackMotion>()
209                ;
210
211        else if(!name.compare("OutCircMotion"))
212            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutCircMotion>()
213                ;
214
215        else if(!name.compare("InCircMotion"))
216            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InCircMotion>()
217                ;
218
219        else if(!name.compare("InOutCircMotion"))
220            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutCircMotion>()
221                ;
222
223        else if(!name.compare("OutExpoMotion"))
224            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutExpoMotion>()
225                ;
226
227        else if(!name.compare("InExpoMotion"))
228            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InExpoMotion>()
229                ;
230
231        else if(!name.compare("InOutExpoMotion"))
232            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutExpoMotion>()
233                ;
234
235        else EASE_MOTION_SAMPLER->setMotion<osgAnimation::LinearMotion>();
236
237        return true;
238    }
239
240    bool mouseEnter(double, double, const osgWidget::WindowManager*) {
241        setColor(0.9f, 0.6f, 0.1f, 1.0f);
242
243        return true;
244    }
245
246    bool mouseLeave(double, double, const osgWidget::WindowManager*) {
247        setColor(0.3f, 0.3f, 0.3f, 1.0f);
248
249        return true;
250    }
251};
252
253class ColorLabelMenu: public ColorLabel {
254    osg::ref_ptr<osgWidget::Table> _window;
255
256public:
257    ColorLabelMenu(const char* label):
258        ColorLabel(label) {
259        _window = new osgWidget::Table(std::string("Menu_") + label, 6, 5);
260
261        _window->addWidget(new ColorLabel("OutQuadMotion"), 0, 0);
262        _window->addWidget(new ColorLabel("InQuadMotion"), 1, 0);
263        _window->addWidget(new ColorLabel("InOutQuadMotion"), 2, 0);
264        _window->addWidget(new ColorLabel("OutCubicMotion"), 3, 0);
265        _window->addWidget(new ColorLabel("InCubicMotion"), 4, 0);
266        _window->addWidget(new ColorLabel("InOutCubicMotion"), 5, 0);
267
268        _window->addWidget(new ColorLabel("OutQuartMotion"), 0, 1);
269        _window->addWidget(new ColorLabel("InQuartMotion"), 1, 1);
270        _window->addWidget(new ColorLabel("InOutQuartMotion"), 2, 1);
271        _window->addWidget(new ColorLabel("OutBounceMotion"), 3, 1);
272        _window->addWidget(new ColorLabel("InBounceMotion"), 4, 1);
273        _window->addWidget(new ColorLabel("InOutBounceMotion"), 5, 1);
274
275        _window->addWidget(new ColorLabel("OutElasticMotion"), 0, 2);
276        _window->addWidget(new ColorLabel("InElasticMotion"), 1, 2);
277        _window->addWidget(new ColorLabel("InOutElasticMotion"), 2, 2);
278        _window->addWidget(new ColorLabel("OutSineMotion"), 3, 2);
279        _window->addWidget(new ColorLabel("InSineMotion"), 4, 2);
280        _window->addWidget(new ColorLabel("InOutSineMotion"), 5, 2);
281
282        _window->addWidget(new ColorLabel("OutBackMotion"), 0, 3);
283        _window->addWidget(new ColorLabel("InBackMotion"), 1, 3);
284        _window->addWidget(new ColorLabel("InOutBackMotion"), 2, 3);
285        _window->addWidget(new ColorLabel("OutCircMotion"), 3, 3);
286        _window->addWidget(new ColorLabel("InCircMotion"), 4, 3);
287        _window->addWidget(new ColorLabel("InOutCircMotion"), 5, 3);
288
289        _window->addWidget(new ColorLabel("OutExpoMotion"), 0, 4);
290        _window->addWidget(new ColorLabel("InExpoMotion"), 1, 4);
291        _window->addWidget(new ColorLabel("InOutExpoMotion"), 2, 4);
292        _window->addWidget(new ColorLabel("Linear"), 3, 4);
293
294        _window->resize();
295    }
296
297    void managed(osgWidget::WindowManager* wm) {
298        osgWidget::Label::managed(wm);
299
300        wm->addChild(_window.get());
301
302        _window->hide();
303    }
304
305    void positioned() {
306        osgWidget::Label::positioned();
307
308        _window->setOrigin(_parent->getX(), _parent->getY() +  _parent->getHeight());
309    }
310
311    bool mousePush(double, double, const osgWidget::WindowManager*) {
312        if(!_window->isVisible()) _window->show();
313
314        else _window->hide();
315
316        return true;
317    }
318};
319
320int main(int argc, char** argv) {
321    osgViewer::Viewer viewer;
322
323    osgWidget::WindowManager* wm = new osgWidget::WindowManager(
324        &viewer,
325        WINDOW_WIDTH,
326        WINDOW_HEIGHT,
327        MASK_2D
328        );
329
330    osgWidget::Window* menu = new osgWidget::Box("menu", osgWidget::Box::HORIZONTAL);
331
332    menu->addWidget(new ColorLabelMenu("Choose EaseMotion"));
333    menu->getBackground()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
334    menu->setPosition(15.0f, 15.0f, 0.0f);
335
336    wm->addChild(menu);
337
338    osg::Group*           group = new osg::Group();
339    osg::Geode*           geode = new osg::Geode();
340    osg::MatrixTransform* mt    = new osg::MatrixTransform();
341
342    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 4.0f)));
343
344    EASE_MOTION_SAMPLER = new EaseMotionSampler(osg::Vec3(50.0f, 0.0f, 0.0f));
345    EASE_MOTION_GEODE   = new osg::Geode();
346
347    mt->addChild(geode);
348    mt->setUpdateCallback(EASE_MOTION_SAMPLER);
349    mt->setNodeMask(MASK_3D);
350
351    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
352    viewer.getCameraManipulator()->setHomePosition(
353        osg::Vec3d(0.0f, 0.0f, 200.0f),
354        osg::Vec3d(20.0f, 0.0f, 0.0f),
355        osg::Vec3d(0.0f, 1.0f, 0.0f)
356        );
357    viewer.home();
358
359    group->addChild(mt);
360    group->addChild(EASE_MOTION_GEODE);
361
362    return osgWidget::createExample(viewer, wm, group);
363}
Note: See TracBrowser for help on using the browser.