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

Revision 9459, 7.7 kB (checked in by robert, 6 years ago)

Fixed warnings

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