Added support for new event visitor type into osgGA and osgProducer::Viewer,

and event callback into Drawable.
This commit is contained in:
Robert Osfield
2005-02-25 14:02:48 +00:00
parent 82d8bcd2af
commit 0f61af08bd
11 changed files with 319 additions and 10 deletions

View File

@@ -497,6 +497,27 @@ void Drawable::setUpdateCallback(UpdateCallback* ac)
}
}
void Drawable::setEventCallback(EventCallback* ac)
{
if (_eventCallback==ac) return;
int delta = 0;
if (_eventCallback.valid()) --delta;
if (ac) ++delta;
_eventCallback = ac;
if (delta!=0)
{
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta);
}
}
}
struct ComputeBound : public PrimitiveFunctor
{
ComputeBound():_vertices(0) {}

View File

@@ -62,6 +62,11 @@ bool Geode::addDrawable( Drawable *drawable )
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
}
if (drawable->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+1);
}
dirtyBound();
return true;
@@ -88,12 +93,14 @@ bool Geode::removeDrawable(unsigned int pos,unsigned int numDrawablesToRemove)
}
unsigned int updateCallbackRemoved = 0;
unsigned int eventCallbackRemoved = 0;
for(unsigned i=pos;i<endOfRemoveRange;++i)
{
// remove this Geode from the child parent list.
_drawables[i]->removeParent(this);
// update the number of app calbacks removed
if (_drawables[i]->getUpdateCallback()) ++updateCallbackRemoved;
if (_drawables[i]->getEventCallback()) ++eventCallbackRemoved;
}
_drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange);
@@ -103,6 +110,11 @@ bool Geode::removeDrawable(unsigned int pos,unsigned int numDrawablesToRemove)
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved);
}
if (eventCallbackRemoved)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved);
}
dirtyBound();
return true;
@@ -129,14 +141,23 @@ bool Geode::setDrawable( unsigned int i, Drawable* newDrawable )
Drawable* origDrawable = _drawables[i].get();
int delta = 0;
if (origDrawable->getUpdateCallback()) --delta;
if (newDrawable->getUpdateCallback()) ++delta;
if (delta!=0)
int deltaUpdate = 0;
if (origDrawable->getUpdateCallback()) --deltaUpdate;
if (newDrawable->getUpdateCallback()) ++deltaUpdate;
if (deltaUpdate!=0)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+delta);
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+deltaUpdate);
}
int deltaEvent = 0;
if (origDrawable->getEventCallback()) --deltaEvent;
if (newDrawable->getEventCallback()) ++deltaEvent;
if (deltaEvent!=0)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+deltaEvent);
}
// remove from origDrawable's parent list.
origDrawable->removeParent(this);

View File

@@ -0,0 +1,44 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgGA/EventVisitor>
#include <algorithm>
using namespace osg;
using namespace osgGA;
EventVisitor::EventVisitor():NodeVisitor(UPDATE_VISITOR,TRAVERSE_ALL_CHILDREN)
{
}
EventVisitor::~EventVisitor()
{
}
void EventVisitor::addEvent(GUIEventAdapter* event)
{
_events.push_back(event);
}
void EventVisitor::removeEvent(GUIEventAdapter* event)
{
EventList::iterator itr = std::find(_events.begin(),_events.end(),event);
if (itr!=_events.end()) _events.erase(itr);
}
void EventVisitor::reset()
{
_events.clear();
}

View File

@@ -6,6 +6,7 @@ CXXFILES = \
AnimationPathManipulator.cpp\
MatrixManipulator.cpp\
DriveManipulator.cpp\
EventVisitor.cpp\
FlightManipulator.cpp\
GUIEventAdapter.cpp\
GUIEventHandler.cpp\

View File

@@ -12,9 +12,40 @@
*/
#include <osgGA/GUIEventHandler>
#include <osgGA/EventVisitor>
using namespace osgGA;
void GUIEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
if (ev && ev->getActionAdapter() && !ev->getEventList().empty())
{
for(osgGA::EventVisitor::EventList::iterator itr = ev->getEventList().begin();
itr != ev->getEventList().end();
++itr)
{
handle(*(*itr), *(ev->getActionAdapter()));
}
}
traverse(node,nv);
}
void GUIEventHandler::event(osg::NodeVisitor* nv, osg::Drawable* /*drawable*/)
{
osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
if (ev && ev->getActionAdapter() && !ev->getEventList().empty())
{
for(osgGA::EventVisitor::EventList::iterator itr = ev->getEventList().begin();
itr != ev->getEventList().end();
++itr)
{
handle(*(*itr), *(ev->getActionAdapter()));
}
}
}
void CompositeGUIEventHandler::getUsage(osg::ApplicationUsage& usage) const
{
for (ChildList::const_iterator itr=_children.begin();

View File

@@ -5,6 +5,7 @@
#include <osgDB/Registry>
#include <osgGA/EventVisitor>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
@@ -482,6 +483,10 @@ void Viewer::setUpViewer(unsigned int options)
_updateVisitor->setFrameStamp(_frameStamp.get());
if (!_eventVisitor) _eventVisitor = new osgGA::EventVisitor;
_eventVisitor->setActionAdapter(this);
if (options&TRACKBALL_MANIPULATOR) addCameraManipulator(new osgGA::TrackballManipulator);
if (options&FLIGHT_MANIPULATOR) addCameraManipulator(new osgGA::FlightManipulator);
if (options&DRIVE_MANIPULATOR) addCameraManipulator(new osgGA::DriveManipulator);
@@ -632,6 +637,11 @@ void Viewer::update()
frame_event->adaptFrame(_frameStamp->getReferenceTime());
queue.push_back(frame_event);
if (_eventVisitor.valid())
{
_eventVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
}
// dispatch the events in order of arrival.
for(osgProducer::KeyboardMouseCallback::EventQueue::iterator event_itr=queue.begin();
event_itr!=queue.end();
@@ -644,8 +654,15 @@ void Viewer::update()
{
handled = (*handler_itr)->handle(*(*event_itr),*this);
}
if (!handled && _eventVisitor.valid())
{
_eventVisitor->reset();
_eventVisitor->addEvent(event_itr->get());
getTopMostSceneData()->accept(*_eventVisitor);
}
}
if (osgDB::Registry::instance()->getDatabasePager())
{
// update the scene graph by remove expired subgraphs and merge newly loaded subgraphs
@@ -661,6 +678,7 @@ void Viewer::update()
getTopMostSceneData()->accept(*_updateVisitor);
}
// update the main producer camera
if (_keyswitchManipulator.valid() && _keyswitchManipulator->getCurrentMatrixManipulator())
{