Skip to content

Commit

Permalink
Introduced new scheme for handling mouse events with osgViewer. The n…
Browse files Browse the repository at this point in the history
…ew scheme enables robust event handling even when using distortion correction render to texture Cameras.
  • Loading branch information
robertosfield committed May 3, 2013
1 parent bd81d96 commit 6e69fe0
Show file tree
Hide file tree
Showing 36 changed files with 1,100 additions and 682 deletions.
9 changes: 4 additions & 5 deletions examples/osgcompositeviewer/osgcompositeviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class PickHandler : public osgGA::GUIEventHandler {

~PickHandler() {}

bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
if (!view) return false;
Expand All @@ -71,7 +71,7 @@ class PickHandler : public osgGA::GUIEventHandler {
{
if (_mx==ea.getX() && _my==ea.getY())
{
pick(view, ea.getX(), ea.getY());
pick(view, ea);
}
break;
}
Expand All @@ -81,13 +81,13 @@ class PickHandler : public osgGA::GUIEventHandler {
return false;
}

void pick(osgViewer::View* view, float x, float y)
void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& event)
{
osg::Node* node = 0;
osg::Group* parent = 0;

osgUtil::LineSegmentIntersector::Intersections intersections;
if (view->computeIntersections(x, y, intersections))
if (view->computeIntersections(event, intersections))
{
osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
osg::NodePath& nodePath = intersection.nodePath;
Expand All @@ -98,7 +98,6 @@ class PickHandler : public osgGA::GUIEventHandler {
// now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked"
if (parent && node)
{

osgFX::Scribe* parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent);
if (!parentAsScribe)
{
Expand Down
201 changes: 160 additions & 41 deletions examples/osgkeystone/osgkeystone.cpp

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions examples/osglauncher/osglauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class PickHandler : public osgGA::GUIEventHandler {

bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);

std::string pick(float x, float y);
std::string pick(const osgGA::GUIEventAdapter& event);

void highlight(const std::string& name)
{
Expand All @@ -83,15 +83,15 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
case(osgGA::GUIEventAdapter::FRAME):
case(osgGA::GUIEventAdapter::MOVE):
{
//osg::notify(osg::NOTICE)<<"MOVE "<<ea.getX()<<ea.getY()<<std::endl;
std::string picked_name = pick(ea.getX(),ea.getY());
// osg::notify(osg::NOTICE)<<"MOVE "<<ea.getX()<<", "<<ea.getY()<<std::endl;
std::string picked_name = pick(ea);
highlight(picked_name);
return false;
}
case(osgGA::GUIEventAdapter::PUSH):
{
//osg::notify(osg::NOTICE)<<"PUSH "<<ea.getX()<<ea.getY()<<std::endl;
std::string picked_name = pick(ea.getX(),ea.getY());
// osg::notify(osg::NOTICE)<<"PUSH "<<ea.getX()<<", "<<ea.getY()<<std::endl;
std::string picked_name = pick(ea);
if (!picked_name.empty())
{
runApp(picked_name);
Expand All @@ -108,10 +108,10 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
}


std::string PickHandler::pick(float x, float y)
std::string PickHandler::pick(const osgGA::GUIEventAdapter& event)
{
osgUtil::LineSegmentIntersector::Intersections intersections;
if (_viewer->computeIntersections(x, y, intersections))
if (_viewer->computeIntersections(event, intersections))
{
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
hitr != intersections.end();
Expand Down
4 changes: 2 additions & 2 deletions examples/osgmovie/osgmovie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
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));
(nv==0 ? view->computeIntersections(ea, intersections) :
view->computeIntersections(ea, nv->getNodePath(), intersections));

if (foundIntersection)
{
Expand Down
2 changes: 1 addition & 1 deletion examples/osgmultiplemovies/osgmultiplemovies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction

osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
osgUtil::LineSegmentIntersector::Intersections intersections;
bool foundIntersection = view==0 ? false : view->computeIntersections(ea.getX(), ea.getY(), intersections);
bool foundIntersection = view==0 ? false : view->computeIntersections(ea, intersections);

if (foundIntersection)
{
Expand Down
2 changes: 1 addition & 1 deletion examples/osgoccluder/osgoccluder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAct
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
osgUtil::LineSegmentIntersector::Intersections intersections;
if (view && view->computeIntersections(ea.getX(), ea.getY(), intersections))
if (view && view->computeIntersections(ea, intersections))
{
const osgUtil::LineSegmentIntersector::Intersection& hit = *(intersections.begin());
if (hit.matrix.valid()) addPoint(hit.localIntersectionPoint * (*hit.matrix));
Expand Down
11 changes: 1 addition & 10 deletions examples/osgoscdevice/osgoscdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,8 @@ void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
std::string gdlist="";
float x = ea.getX();
float y = ea.getY();
#if 0
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y);
osgUtil::IntersectionVisitor iv(picker.get());
view->getCamera()->accept(iv);
if (picker->containsIntersections())
if (view->computeIntersections(ea, intersections))
{
intersections = picker->getIntersections();
#else
if (view->computeIntersections(x,y,intersections))
{
#endif
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
hitr != intersections.end();
++hitr)
Expand Down
4 changes: 2 additions & 2 deletions examples/osgparticleeffects/osgparticleeffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ class PickHandler : public osgGA::GUIEventHandler {
{
osg::Group* root = dynamic_cast<osg::Group*>(viewer->getSceneData());
if (!root) return;

osgUtil::LineSegmentIntersector::Intersections intersections;
if (viewer->computeIntersections(ea.getX(),ea.getY(),intersections))
if (viewer->computeIntersections(ea,intersections))
{
const osgUtil::LineSegmentIntersector::Intersection& hit = *intersections.begin();

Expand Down
14 changes: 2 additions & 12 deletions examples/osgpick/osgpick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,9 @@ void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
osgUtil::LineSegmentIntersector::Intersections intersections;

std::string gdlist="";
float x = ea.getX();
float y = ea.getY();
#if 0
osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y);
osgUtil::IntersectionVisitor iv(picker.get());
view->getCamera()->accept(iv);
if (picker->containsIntersections())
{
intersections = picker->getIntersections();
#else
if (view->computeIntersections(x,y,intersections))

if (view->computeIntersections(ea,intersections))
{
#endif
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
hitr != intersections.end();
++hitr)
Expand Down
2 changes: 1 addition & 1 deletion examples/osgwidgetbox/osgwidgetbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ struct ColorWidget: public osgWidget::Widget {
}

bool mouseOver(double x, double y, const osgWidget::WindowManager*) {

osgWidget::Color c = getImageColorAtPointerXY(x, y);

if(c.a() < 0.001f) {
// osgWidget::warn() << "Transparent Pixel: " << x << " " << y << std::endl;

return false;
}

return true;
}

Expand Down
7 changes: 7 additions & 0 deletions include/osgGA/EventQueue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced

/** Set the graphics context associated with this event queue.*/
void setGraphicsContext(osg::GraphicsContext* context) { getCurrentEventState()->setGraphicsContext(context); }

osg::GraphicsContext* getGraphicsContext() { return getCurrentEventState()->getGraphicsContext(); }

const osg::GraphicsContext* getGraphicsContext() const { return getCurrentEventState()->getGraphicsContext(); }

/** Read the window record dimensions from the graphics context. */
void syncWindowRectangleWithGraphcisContext();


/** Set the mouse input range.*/
Expand Down
89 changes: 88 additions & 1 deletion include/osgGA/GUIEventAdapter
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,59 @@

namespace osgGA{

struct PointerData : public osg::Referenced
{
PointerData():
object(0),
x(0.0f),
xMin(-1.0f),
xMax(1.0f),
y(0.0f),
yMin(-1.0f),
yMax(1.0f) {}

PointerData(osg::Object* obj, float in_x, float in_xMin, float in_xMax, float in_y, float in_yMin, float in_yMax):
object(obj),
x(in_x),
xMin(in_xMin),
xMax(in_xMax),
y(in_y),
yMin(in_yMin),
yMax(in_yMax) {}

PointerData(const PointerData& pd):
object(pd.object),
x(pd.x),
xMin(pd.xMin),
xMax(pd.xMax),
y(pd.y),
yMin(pd.yMin),
yMax(pd.yMax) {}

PointerData& operator = (const PointerData& pd)
{
if (&pd==this) return *this;

object = pd.object;
x = pd.x;
xMin = pd.xMin;
xMax = pd.xMax;
y = pd.y;
yMin = pd.yMin;
yMax = pd.yMax;

return *this;
}

osg::observer_ptr<osg::Object> object;
float x, xMin, xMax;
float y, yMin, yMax;

float getXnormalized() const { return (x-xMin)/(xMax-xMin)*2.0f-1.0f; }
float getYnormalized() const { return (y-yMin)/(yMax-yMin)*2.0f-1.0f; }
};


/** Event class for storing Keyboard, mouse and window events.
*/
class OSGGA_EXPORT GUIEventAdapter : public osg::Object
Expand Down Expand Up @@ -425,6 +477,7 @@ public:


void setGraphicsContext(osg::GraphicsContext* context) { _context = context; }
osg::GraphicsContext* getGraphicsContext() { return _context.get(); }
const osg::GraphicsContext* getGraphicsContext() const { return _context.get(); }


Expand Down Expand Up @@ -514,6 +567,21 @@ public:
/** get current mouse y position.*/
float getY() const { return _my; }

#if 1
inline float getXnormalized() const
{
return _pointerDataList.size()>=1 ?
_pointerDataList[_pointerDataList.size()-1]->getXnormalized():
2.0f*(getX()-getXmin())/(getXmax()-getXmin())-1.0f;
}

inline float getYnormalized() const
{
if (_pointerDataList.size()>=1) return _pointerDataList[_pointerDataList.size()-1]->getYnormalized();
if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
}
#else
/**
* return the current mouse x value normalized to the range of -1 to 1.
* -1 would be the left hand side of the window.
Expand All @@ -533,7 +601,7 @@ public:
if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
}

#endif
/// set mouse-Y orientation (mouse-Y increases upwards or downwards).
void setMouseYOrientation(MouseYOrientation myo) { _mouseYOrientation = myo; }

Expand Down Expand Up @@ -616,6 +684,22 @@ public:
TouchData* getTouchData() const { return _touchData.get(); }
bool isMultiTouchEvent() const { return (_touchData.valid()); }


typedef std::vector< osg::ref_ptr<PointerData> > PointerDataList;
void setPointerDataList(const PointerDataList& pdl) { _pointerDataList = pdl; }
PointerDataList& getPointerDataList() { return _pointerDataList; }
const PointerDataList& getPointerDataList() const { return _pointerDataList; }

unsigned int getNumPointerData() const { return _pointerDataList.size(); }
PointerData* getPointerData(unsigned int i) { return _pointerDataList[i].get(); }
const PointerData* getPointerData(unsigned int i) const { return _pointerDataList[i].get(); }

PointerData* getPointerData(osg::Object* obj) { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
const PointerData* getPointerData(osg::Object* obj) const { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
void addPointerData(PointerData* pd) { _pointerDataList.push_back(pd); }

void copyPointerDataFrom(const osgGA::GUIEventAdapter& sourceEvent);

protected:

/** Force users to create on heap, so that multiple referencing is safe.*/
Expand Down Expand Up @@ -664,6 +748,9 @@ public:
TabletPen _tabletPen;

osg::ref_ptr<TouchData> _touchData;


PointerDataList _pointerDataList;
};

}
Expand Down
5 changes: 5 additions & 0 deletions include/osgUtil/LineSegmentIntersector
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector

const osg::Vec3& getLocalIntersectNormal() const { return localIntersectionNormal; }
osg::Vec3 getWorldIntersectNormal() const { return matrix.valid() ? osg::Matrix::transform3x3(osg::Matrix::inverse(*matrix),localIntersectionNormal) : localIntersectionNormal; }

/** convinience function for mapping the intersection point to any textures assigned to the objects intersected.
* Returns the Texture pointer and texture coords of object hit when a texture is available on the object, returns NULL otherwise.*/
osg::Texture* getTextureLookUp(osg::Vec3& tc) const;

};

typedef std::multiset<Intersection> Intersections;
Expand Down
6 changes: 6 additions & 0 deletions include/osgViewer/CompositeViewer
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ class OSGVIEWER_EXPORT CompositeViewer : public ViewerBase

virtual void viewerInit();

void generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event);
void generatePointerData(osgGA::GUIEventAdapter& event);
void reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event);

typedef std::vector< osg::ref_ptr<osgViewer::View> > RefViews;
RefViews _views;

Expand All @@ -135,6 +139,8 @@ class OSGVIEWER_EXPORT CompositeViewer : public ViewerBase

osg::observer_ptr<osg::Camera> _cameraWithFocus;
osg::observer_ptr<osgViewer::View> _viewWithFocus;

osg::ref_ptr<osgGA::GUIEventAdapter> _previousEvent;

};

Expand Down
25 changes: 17 additions & 8 deletions include/osgViewer/View
Original file line number Diff line number Diff line change
Expand Up @@ -227,20 +227,29 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter
/** Return true if this view contains a specified camera.*/
bool containsCamera(const osg::Camera* camera) const;

/** Get the camera which contains the pointer position x,y specified in the master camera's window/eye coordinates.
* Also passes back the local window coordinatess for the graphics context associated with the camera. */

/** deprecated. */
const osg::Camera* getCameraContainingPosition(float x, float y, float& local_x, float& local_y) const;

/** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified node.
* Note, when a master camera has slaves and no viewport itself, its coordinate frame will be in clip space i.e. -1,-1 to 1,1,
* while if it has a viewport the coordintates will be relative to its viewport dimensions.
* Mouse events handled by the view will automatically be attached to the master camera window/clip coordinates so that they can be passed
* directly to the computeIntersections method. */
/** deprecated. */
bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);

/** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */
/** deprecated. */
bool computeIntersections(float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);


/** Compute intersections of a ray, starting the current mouse position, through the specified camera. */
bool computeIntersections(const osgGA::GUIEventAdapter& ea, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);

/** Compute intersections of a ray, starting the current mouse position, through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */
bool computeIntersections(const osgGA::GUIEventAdapter& ea, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);


/** Compute intersections of a ray through the specified camera. */
bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);

/** Compute intersections of a ray through the specified camera and a specified nodePath's subgraph. */
bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);

virtual void requestRedraw();
virtual void requestContinuousUpdate(bool needed=true);
Expand Down
Loading

0 comments on commit 6e69fe0

Please sign in to comment.