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

Revision 13890, 7.5 kB (checked in by robert, 14 hours ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • Property svn:eol-style set to native
Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
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 <iostream>
16#include <osgDB/ReadFile>
17#include <osgViewer/ViewerEventHandlers>
18#include <osgGA/TrackballManipulator>
19#include <osgGA/FlightManipulator>
20#include <osgGA/DriveManipulator>
21#include <osgGA/KeySwitchMatrixManipulator>
22#include <osgGA/StateSetManipulator>
23#include <osgGA/AnimationPathManipulator>
24#include <osgGA/TerrainManipulator>
25
26#include <osgAnimation/Bone>
27#include <osgAnimation/Skeleton>
28#include <osgAnimation/RigGeometry>
29#include <osgAnimation/Timeline>
30#include <osgAnimation/AnimationManagerBase>
31#include <osgAnimation/TimelineAnimationManager>
32
33#include <osgAnimation/ActionStripAnimation>
34#include <osgAnimation/ActionBlendIn>
35#include <osgAnimation/ActionBlendOut>
36#include <osgAnimation/ActionAnimation>
37
38
39struct NoseBegin : public osgAnimation::Action::Callback
40{
41    virtual void operator()(osgAnimation::Action* action, osgAnimation::ActionVisitor* nv)
42    {
43        std::cout << "sacrebleu, it scratches my nose, let me scratch it" << std::endl;
44        std::cout << "process NoseBegin call back " << action->getName() << std::endl << std::endl;
45    }
46};
47
48struct NoseEnd : public osgAnimation::Action::Callback
49{
50    virtual void operator()(osgAnimation::Action* action, osgAnimation::ActionVisitor* nv)
51    {
52        std::cout << "shhhrt shrrrrt shhhhhhrrrrt, haaa it's better"<< std::endl;
53        std::cout << "process NoseEnd call back " << action->getName() << std::endl << std::endl;
54    }
55};
56
57struct ExampleTimelineUsage : public osgGA::GUIEventHandler
58{
59    osg::ref_ptr<osgAnimation::ActionStripAnimation> _mainLoop;
60    osg::ref_ptr<osgAnimation::ActionStripAnimation> _scratchHead;
61    osg::ref_ptr<osgAnimation::ActionStripAnimation> _scratchNose;
62    osg::ref_ptr<osgAnimation::TimelineAnimationManager> _manager;
63
64    bool _releaseKey;
65
66    ExampleTimelineUsage(osgAnimation::TimelineAnimationManager* manager)
67    {
68        _releaseKey = false;
69        _manager = manager;
70
71        const osgAnimation::AnimationList& list = _manager->getAnimationList();
72        osgAnimation::AnimationMap map;
73        for (osgAnimation::AnimationList::const_iterator it = list.begin(); it != list.end(); it++)
74            map[(*it)->getName()] = *it;
75
76        _mainLoop = new osgAnimation::ActionStripAnimation(map["Idle_Main"].get(),0.0,0.0);
77        _mainLoop->setLoop(0); // means forever
78
79        _scratchHead = new osgAnimation::ActionStripAnimation(map["Idle_Head_Scratch.02"].get(),0.2,0.3);
80        _scratchHead->setLoop(1); // one time
81
82        map["Idle_Nose_Scratch.01"]->setDuration(10.0); // set this animation duration to 10 seconds
83        _scratchNose = new osgAnimation::ActionStripAnimation(map["Idle_Nose_Scratch.01"].get(),0.2,0.3);
84        _scratchNose->setLoop(1); // one time
85
86        // add the main loop at priority 0 at time 0.
87
88        osgAnimation::Timeline* tml = _manager->getTimeline();
89        tml->play();
90        tml->addActionAt(0.0, _mainLoop.get(), 0);
91
92
93        // add a scratch head priority 1 at 3.0 second.
94        tml->addActionAt(5.0, _scratchHead.get(), 1);
95
96        // populate time with scratch head
97        for (int i = 1; i < 20; i++)
98        {
99            // we add a scratch head priority 1 each 10 second
100            // note:
101            //      it's possible to add the same instance more then once on the timeline
102            //      the only things you need to take care is if you remove it. It will remove
103            //      all instance that exist on the timeline. If you need to differtiate
104            //      it's better to create a new instance
105            tml->addActionAt(5.0 + 10.0 * i, _scratchHead.get(), 1);
106        }
107
108        // we will add the scratch nose action only when the player hit a key
109        // in the operator()
110
111        // now we will add callback at end and begin of animation of Idle_Nose_Scratch.02
112        _scratchNose->setCallback(0.0, new NoseBegin);
113        _scratchNose->setCallback(_scratchNose->getNumFrames()-1, new NoseEnd);
114    }
115
116    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&)
117    {
118        if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
119        {
120            _releaseKey = true;
121        }
122        return false;
123    }
124
125    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
126    {
127        if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
128        {
129            if (_releaseKey) // we hit a key and release it execute an action
130            {
131                osgAnimation::Timeline* tml = _manager->getTimeline();
132                // dont play if already playing
133                if (!tml->isActive(_scratchNose.get()))
134                {
135                    // add this animation on top of two other
136                    // we add one to evaluate the animation at the next frame, else we
137                    // will miss the current frame
138                    tml->addActionAt(tml->getCurrentFrame() + 1, _scratchNose.get(), 2);
139                }
140                _releaseKey = false;
141            }
142            traverse(node, nv);
143        }
144        else
145        {
146            osgGA::GUIEventHandler::operator()(node, nv);
147        }
148    }
149
150};
151
152
153int main (int argc, char* argv[])
154{
155    std::cerr << "This example works only with nathan.osg" << std::endl;
156
157    osg::ArgumentParser psr(&argc, argv);
158
159    osgViewer::Viewer viewer(psr);
160
161    std::string file = "nathan.osg";
162    if(argc >= 2)
163        file = psr[1];
164
165    // replace the manager
166    osg::Group* root = dynamic_cast<osg::Group*>(osgDB::readNodeFile(file));
167    if (!root) {
168        osg::notify(osg::FATAL) << "can't read file " << file << std::endl;
169        return 1;
170    }
171    osgAnimation::AnimationManagerBase* animationManager = dynamic_cast<osgAnimation::AnimationManagerBase*>(root->getUpdateCallback());
172    if(!animationManager)
173    {
174        osg::notify(osg::FATAL) << "Did not find AnimationManagerBase updateCallback needed to animate elements" << std::endl;
175        return 1;
176    }
177
178    osg::ref_ptr<osgAnimation::TimelineAnimationManager> tl = new osgAnimation::TimelineAnimationManager(*animationManager);
179    root->setUpdateCallback(tl.get());
180
181    ExampleTimelineUsage* callback = new ExampleTimelineUsage(tl.get());
182    root->setEventCallback(callback);
183    root->getUpdateCallback()->addNestedCallback(callback);
184
185
186
187    // add the state manipulator
188    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
189
190    // add the thread model handler
191    viewer.addEventHandler(new osgViewer::ThreadingHandler);
192
193    // add the window size toggle handler
194    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
195
196    // add the stats handler
197    viewer.addEventHandler(new osgViewer::StatsHandler);
198
199    // add the help handler
200    viewer.addEventHandler(new osgViewer::HelpHandler(psr.getApplicationUsage()));
201
202    // add the LOD Scale handler
203    viewer.addEventHandler(new osgViewer::LODScaleHandler);
204
205    // add the screen capture handler
206    viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
207
208    viewer.setSceneData(root);
209
210    return viewer.run();
211}
212
Note: See TracBrowser for help on using the browser.