Added sendPointerEvent and sendKeyEvent virtual methods to osg::Image to
facilitate the subclassing of Image providing interactive behaviours so as used in the vnc interactive VncImage class. osgViewer::InteractiveImageHandler provides an event handler that convertes osgGA mouse and keyboard events into the coordinate frame of an image based on ray intersection with geometry in the associated subgraph. Changed the ordering of events processing in Viewer and CompositeViewer to allow scene graph event handlers to take precidence over viewer event handlers and camera manipulators
This commit is contained in:
@@ -828,33 +828,6 @@ void CompositeViewer::eventTraversal()
|
||||
|
||||
if (_done) return;
|
||||
|
||||
for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
|
||||
veitr != viewEventsMap.end();
|
||||
++veitr)
|
||||
{
|
||||
View* view = veitr->first;
|
||||
_eventVisitor->setActionAdapter(view);
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
|
||||
itr != veitr->second.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
|
||||
hitr != view->getEventHandlers().end();
|
||||
++hitr)
|
||||
{
|
||||
(*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
|
||||
}
|
||||
|
||||
if (view->getCameraManipulator())
|
||||
{
|
||||
view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_eventVisitor.valid())
|
||||
{
|
||||
_eventVisitor->setFrameStamp(getFrameStamp());
|
||||
@@ -898,6 +871,49 @@ void CompositeViewer::eventTraversal()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
|
||||
veitr != viewEventsMap.end();
|
||||
++veitr)
|
||||
{
|
||||
View* view = veitr->first;
|
||||
_eventVisitor->setActionAdapter(view);
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
|
||||
itr != veitr->second.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
|
||||
hitr != view->getEventHandlers().end();
|
||||
++hitr)
|
||||
{
|
||||
(*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
|
||||
veitr != viewEventsMap.end();
|
||||
++veitr)
|
||||
{
|
||||
View* view = veitr->first;
|
||||
_eventVisitor->setActionAdapter(view);
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
|
||||
itr != veitr->second.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
if (view->getCameraManipulator())
|
||||
{
|
||||
view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (getStats() && getStats()->collectStats("event"))
|
||||
|
||||
@@ -804,26 +804,6 @@ void Viewer::eventTraversal()
|
||||
|
||||
if (_done) return;
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = events.begin();
|
||||
itr != events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
for(EventHandlers::iterator hitr = _eventHandlers.begin();
|
||||
hitr != _eventHandlers.end();
|
||||
++hitr)
|
||||
{
|
||||
(*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this, 0, 0);
|
||||
}
|
||||
|
||||
if (_cameraManipulator.valid())
|
||||
{
|
||||
_cameraManipulator->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_eventVisitor.valid() && getSceneData())
|
||||
{
|
||||
_eventVisitor->setFrameStamp(getFrameStamp());
|
||||
@@ -858,6 +838,33 @@ void Viewer::eventTraversal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = events.begin();
|
||||
itr != events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
|
||||
for(EventHandlers::iterator hitr = _eventHandlers.begin();
|
||||
hitr != _eventHandlers.end();
|
||||
++hitr)
|
||||
{
|
||||
(*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(osgGA::EventQueue::Events::iterator itr = events.begin();
|
||||
itr != events.end();
|
||||
++itr)
|
||||
{
|
||||
osgGA::GUIEventAdapter* event = itr->get();
|
||||
if (_cameraManipulator.valid())
|
||||
{
|
||||
_cameraManipulator->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this);
|
||||
}
|
||||
}
|
||||
|
||||
if (getStats() && getStats()->collectStats("event"))
|
||||
{
|
||||
double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osg/Geometry>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
@@ -602,4 +603,102 @@ void LODScaleHandler::getUsage(osg::ApplicationUsage& usage) const
|
||||
}
|
||||
|
||||
|
||||
bool InteractiveImageHandler::mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const
|
||||
{
|
||||
osgUtil::LineSegmentIntersector::Intersections intersections;
|
||||
bool foundIntersection = view==0 ? false :
|
||||
(nv==0 ? view->computeIntersections(ea.getX(), ea.getY(), intersections) :
|
||||
view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections));
|
||||
|
||||
if (foundIntersection)
|
||||
{
|
||||
|
||||
osg::Vec2 tc(0.5f,0.5f);
|
||||
|
||||
// use the nearest intersection
|
||||
const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin());
|
||||
osg::Drawable* drawable = intersection.drawable.get();
|
||||
osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
|
||||
osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
|
||||
if (vertices)
|
||||
{
|
||||
// get the vertex indices.
|
||||
const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList;
|
||||
const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList;
|
||||
|
||||
if (indices.size()==3 && ratios.size()==3)
|
||||
{
|
||||
unsigned int i1 = indices[0];
|
||||
unsigned int i2 = indices[1];
|
||||
unsigned int i3 = indices[2];
|
||||
|
||||
float r1 = ratios[0];
|
||||
float r2 = ratios[1];
|
||||
float r3 = ratios[2];
|
||||
|
||||
osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
|
||||
osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
|
||||
if (texcoords_Vec2Array)
|
||||
{
|
||||
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
|
||||
osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
|
||||
osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
|
||||
osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
|
||||
tc = tc1*r1 + tc2*r2 + tc3*r3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
x = int( float(_image->s()) * tc.x() );
|
||||
y = int( float(_image->t()) * tc.y() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool InteractiveImageHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (ea.getHandled()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::MOVE):
|
||||
case(osgGA::GUIEventAdapter::DRAG):
|
||||
case(osgGA::GUIEventAdapter::PUSH):
|
||||
case(osgGA::GUIEventAdapter::RELEASE):
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
int x,y;
|
||||
if (mousePosition(view, nv, ea, x, y))
|
||||
{
|
||||
_image->sendPointerEvent(x, y, ea.getButtonMask());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
case(osgGA::GUIEventAdapter::KEYUP):
|
||||
{
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||
int x,y;
|
||||
bool sendKeyEvent = mousePosition(view, nv, ea, x, y);
|
||||
|
||||
if (sendKeyEvent)
|
||||
{
|
||||
_image->sendKeyEvent(ea.getKey(), ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user