root/OpenSceneGraph/trunk/src/osgPresentation/deprecated/Timeout.cpp @ 13890

Revision 13890, 12.4 kB (checked in by robert, 10 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."

Line 
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 <osgPresentation/deprecated/Timeout>
15#include <osgUtil/CullVisitor>
16#include <osgGA/EventVisitor>
17
18using namespace osgPresentation;
19
20
21class OperationVisitor : public osg::NodeVisitor
22{
23public:
24
25    enum Operation
26    {
27        ENTER,
28        LEAVE,
29        RESET
30    };
31
32    OperationVisitor(Operation op) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _operation(op), _sleepTime(0.0) {}
33
34    void apply(osg::Node& node)
35    {
36        if (node.getStateSet()) process(node.getStateSet());
37        traverse(node);
38    }
39
40    void apply(osg::Geode& geode)
41    {
42        apply(static_cast<osg::Node&>(geode));
43
44        for(unsigned int i=0;i<geode.getNumDrawables();++i)
45        {
46            osg::Drawable* drawable = geode.getDrawable(i);
47            if (drawable->getStateSet()) process(drawable->getStateSet());
48        }
49    }
50
51    virtual void process(osg::StateSet* ss)
52    {
53        for(unsigned int i=0;i<ss->getTextureAttributeList().size();++i)
54        {
55            osg::Texture* texture = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
56            osg::Image* image = texture ? texture->getImage(0) : 0;
57            osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image);
58            if (imageStream) process(imageStream);
59        }
60    }
61
62    void process(osg::ImageStream* video)
63    {
64        if (_operation==ENTER)
65        {
66            video->rewind();
67            video->play();
68
69            _sleepTime = 0.2;
70        }
71        else if (_operation==LEAVE)
72        {
73            video->pause();
74        }
75        else if (_operation==RESET)
76        {
77            video->rewind();
78
79            _sleepTime = 0.2;
80        }
81    }
82
83    double sleepTime() const { return _sleepTime; }
84
85    Operation   _operation;
86    double      _sleepTime;
87};
88
89
90HUDSettings::HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask):
91    _slideDistance(slideDistance),
92    _eyeOffset(eyeOffset),
93    _leftMask(leftMask),
94    _rightMask(rightMask)
95{
96}
97
98HUDSettings::~HUDSettings()
99{
100}
101
102bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
103{
104    matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
105
106    if (nv)
107    {
108        if (nv->getTraversalMask()==_leftMask)
109        {
110            matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
111        }
112        else if (nv->getTraversalMask()==_rightMask)
113        {
114            matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
115        }
116    }
117
118    return true;
119}
120
121bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
122{
123    osg::Matrix modelView;
124    getModelViewMatrix(modelView,nv);
125    matrix.invert(modelView);
126    return true;
127}
128
129
130
131
132Timeout::Timeout(HUDSettings* hudSettings):
133    _previousFrameNumber(-1),
134    _timeOfLastEvent(0.0),
135    _displayTimeout(false),
136    _idleDurationBeforeTimeoutDisplay(DBL_MAX),
137    _idleDurationBeforeTimeoutAction(DBL_MAX),
138    _keyStartsTimoutDisplay(0),
139    _keyDismissTimoutDisplay(0),
140    _keyRunTimeoutAction(0)
141{
142    _hudSettings = hudSettings;
143    setCullingActive(false);
144    setNumChildrenRequiringEventTraversal(1);
145}
146
147/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
148Timeout::Timeout(const Timeout& timeout,const osg::CopyOp& copyop):
149    osg::Transform(timeout, copyop),
150    _hudSettings(timeout._hudSettings)
151{
152    setDataVariance(osg::Object::DYNAMIC);
153    setReferenceFrame(osg::Transform::ABSOLUTE_RF);
154}
155
156Timeout::~Timeout()
157{
158}
159
160bool Timeout::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
161{
162    if (_hudSettings.valid()) return _hudSettings->getModelViewMatrix(matrix,nv);
163    else return false;
164}
165
166bool Timeout::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
167{
168    if (_hudSettings.valid()) return _hudSettings->getInverseModelViewMatrix(matrix,nv);
169    else return false;
170}
171
172void Timeout::broadcastEvent(osgViewer::Viewer* viewer, const osgPresentation::KeyPosition& keyPos)
173{
174    osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
175
176    if (keyPos._key!=0) event->setEventType(osgGA::GUIEventAdapter::KEYDOWN);
177    else event->setEventType(osgGA::GUIEventAdapter::MOVE);
178
179    if (keyPos._key!=0) event->setKey(keyPos._key);
180    if (keyPos._x!=FLT_MAX) event->setX(keyPos._x);
181    if (keyPos._y!=FLT_MAX) event->setY(keyPos._y);
182
183    event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
184
185    // dispatch cloned event to devices
186    osgViewer::View::Devices& devices = viewer->getDevices();
187    for(osgViewer::View::Devices::iterator i = devices.begin(); i != devices.end(); ++i)
188    {
189        if((*i)->getCapabilities() & osgGA::Device::SEND_EVENTS)
190        {
191            (*i)->sendEvent(*event);
192        }
193    }
194}
195void Timeout::traverse(osg::NodeVisitor& nv)
196{
197    if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
198    {
199        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
200        if (_displayTimeout && cv)
201        {
202            osgUtil::RenderStage* previous_stage = cv->getCurrentRenderBin()->getStage();
203
204            osg::ref_ptr<osgUtil::RenderStage> rs = new osgUtil::RenderStage;
205
206            osg::ColorMask* colorMask = previous_stage->getColorMask();
207            rs->setColorMask(colorMask);
208
209            // set up the viewport.
210            osg::Viewport* viewport = previous_stage->getViewport();
211            rs->setViewport( viewport );
212
213            rs->setClearMask(GL_DEPTH_BUFFER_BIT);
214
215            // record the render bin, to be restored after creation
216            // of the render to text
217            osgUtil::RenderBin* previousRenderBin = cv->getCurrentRenderBin();
218
219            // set the current renderbin to be the newly created stage.
220            cv->setCurrentRenderBin(rs.get());
221
222            // traverse the subgraph
223            {
224                Transform::traverse(nv);
225            }
226
227            // restore the previous renderbin.
228            cv->setCurrentRenderBin(previousRenderBin);
229
230            // and the render to texture stage to the current stages
231            // dependancy list.
232            cv->getCurrentRenderBin()->getStage()->addPostRenderStage(rs.get(),0);
233        }
234    }
235    else if (nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
236    {
237        int deltaFrameNumber = (nv.getFrameStamp()->getFrameNumber()-_previousFrameNumber);
238        _previousFrameNumber = nv.getFrameStamp()->getFrameNumber();
239
240        bool needToRecordEventTime = false;
241        bool needToAction = false;
242
243        if (deltaFrameNumber>1)
244        {
245            needToRecordEventTime = true;
246        }
247
248        bool previous_displayTimeout = _displayTimeout;
249        bool needToDismiss = false;
250
251        osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
252        osgViewer::Viewer* viewer = ev ? dynamic_cast<osgViewer::Viewer*>(ev->getActionAdapter()) : 0;
253        if (ev)
254        {
255            osgGA::EventQueue::Events& events = ev->getEvents();
256            for(osgGA::EventQueue::Events::iterator itr = events.begin();
257                itr != events.end();
258                ++itr)
259            {
260                osgGA::GUIEventAdapter* event = (*itr)->asGUIEventAdapter();
261                if (!event) continue;
262
263                bool keyEvent = event->getEventType()==osgGA::GUIEventAdapter::KEYDOWN ||  event->getEventType()==osgGA::GUIEventAdapter::KEYUP;
264
265                if (keyEvent && event->getKey()==_keyStartsTimoutDisplay)
266                {
267                    OSG_NOTICE<<"_keyStartsTimoutDisplay pressed"<<std::endl;
268                    _displayTimeout = true;
269                }
270                else if (keyEvent && event->getKey()==_keyDismissTimoutDisplay)
271                {
272                    OSG_NOTICE<<"_keyDismissTimoutDisplay pressed"<<std::endl;
273                    needToRecordEventTime = true;
274                    needToDismiss = _displayTimeout;
275                    _displayTimeout = false;
276                }
277                else if (keyEvent && event->getKey()==_keyRunTimeoutAction)
278                {
279                    OSG_NOTICE<<"_keyRunTimeoutAction pressed"<<std::endl;
280                    _displayTimeout = false;
281                    needToRecordEventTime = true;
282                    needToAction = true;
283                }
284                else if (event->getEventType()!=osgGA::GUIEventAdapter::FRAME)
285                {
286                    needToRecordEventTime = true;
287                    needToDismiss = _displayTimeout;
288                    _displayTimeout = false;
289                }
290            }
291        }
292
293
294        if (needToRecordEventTime)
295        {
296            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
297        }
298
299        double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0;
300
301        if (timeSinceLastEvent>_idleDurationBeforeTimeoutDisplay)
302        {
303            _displayTimeout = true;
304        }
305
306        if (timeSinceLastEvent>_idleDurationBeforeTimeoutAction)
307        {
308            _displayTimeout = false;
309            needToAction = true;
310            needToDismiss = false;
311        }
312
313        if (!previous_displayTimeout && _displayTimeout)
314        {
315            if (viewer && (_displayBroadcastKeyPos._key!=0 || _displayBroadcastKeyPos._x!=FLT_MAX || _displayBroadcastKeyPos._y!=FLT_MAX))
316            {
317                OSG_NOTICE<<"Doing display broadcast key event"<<_displayBroadcastKeyPos._key<<std::endl;
318                broadcastEvent(viewer, _displayBroadcastKeyPos);
319            }
320
321            OperationVisitor leave(OperationVisitor::ENTER);
322            accept(leave);
323
324            if (leave.sleepTime()!=0.0)
325            {
326                OSG_NOTICE<<"Pausing for "<<leave.sleepTime()<<std::endl;
327                OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*leave.sleepTime()));
328                OSG_NOTICE<<"Finished Pause "<<std::endl;
329            }
330
331        }
332
333
334        if (needToDismiss)
335        {
336            if (viewer && (_dismissBroadcastKeyPos._key!=0 || _dismissBroadcastKeyPos._x!=FLT_MAX || _dismissBroadcastKeyPos._y!=FLT_MAX))
337            {
338                OSG_NOTICE<<"Doing dismiss broadcast key event"<<_dismissBroadcastKeyPos._key<<std::endl;
339                broadcastEvent(viewer, _dismissBroadcastKeyPos);
340            }
341
342            OperationVisitor leave(OperationVisitor::LEAVE);
343            accept(leave);
344        }
345
346        Transform::traverse(nv);
347
348
349        if (needToAction)
350        {
351            OSG_NOTICE<<"Do timeout action"<<std::endl;
352            _previousFrameNumber = -1;
353            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
354
355
356            if (_actionJumpData.requiresJump())
357            {
358                OSG_NOTICE<<"Doing timeout jump"<<std::endl;
359                _actionJumpData.jump(SlideEventHandler::instance());
360            }
361
362            if (_actionKeyPos._key!=0 || _actionKeyPos._x!=FLT_MAX || _actionKeyPos._y!=FLT_MAX)
363            {
364                OSG_NOTICE<<"Doing timeout key event"<<_actionKeyPos._key<<std::endl;
365                if (SlideEventHandler::instance()) SlideEventHandler::instance()->dispatchEvent(_actionKeyPos);
366            }
367
368            if (viewer && (_actionBroadcastKeyPos._key!=0 || _actionBroadcastKeyPos._x!=FLT_MAX || _actionBroadcastKeyPos._y!=FLT_MAX))
369            {
370                OSG_NOTICE<<"Doing timeout broadcast key event"<<_actionBroadcastKeyPos._key<<std::endl;
371                broadcastEvent(viewer, _actionBroadcastKeyPos);
372            }
373
374        }
375
376    }
377    else if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
378    {
379        if (_displayTimeout) Transform::traverse(nv);
380    }
381    else
382    {
383        if (strcmp(nv.className(),"FindOperatorsVisitor")==0)
384        {
385            OSG_NOTICE<<"Timout::traverse() "<<nv.className()<<", ignoring traversal"<<std::endl;
386        }
387        else
388        {
389            Transform::traverse(nv);
390        }
391    }
392
393
394
395}
Note: See TracBrowser for help on using the browser.