Introduced new scheme for handling mouse events with osgViewer. The new scheme enables robust event handling even when using distortion correction render to texture Cameras.
This commit is contained in:
@@ -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.*/
|
||||
|
||||
@@ -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
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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; }
|
||||
|
||||
@@ -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.*/
|
||||
@@ -664,6 +748,9 @@ public:
|
||||
TabletPen _tabletPen;
|
||||
|
||||
osg::ref_ptr<TouchData> _touchData;
|
||||
|
||||
|
||||
PointerDataList _pointerDataList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -93,10 +93,6 @@ class OSGVIEWER_EXPORT Viewer : public ViewerBase, public osgViewer::View
|
||||
|
||||
virtual void updateTraversal();
|
||||
|
||||
void setCameraWithFocus(osg::Camera* camera) { _cameraWithFocus = camera; }
|
||||
osg::Camera* getCameraWithFocus() { return _cameraWithFocus.get(); }
|
||||
const osg::Camera* getCameraWithFocus() const { return _cameraWithFocus.get(); }
|
||||
|
||||
virtual void getCameras(Cameras& cameras, bool onlyActive=true);
|
||||
|
||||
virtual void getContexts(Contexts& contexts, bool onlyValid=true);
|
||||
@@ -119,8 +115,9 @@ class OSGVIEWER_EXPORT Viewer : public ViewerBase, public osgViewer::View
|
||||
|
||||
virtual void viewerInit() { init(); }
|
||||
|
||||
osg::observer_ptr<osg::Camera> _cameraWithFocus;
|
||||
|
||||
void generateSlavePointerData(osg::Camera* camera, osgGA::GUIEventAdapter& event);
|
||||
void generatePointerData(osgGA::GUIEventAdapter& event);
|
||||
void reprojectPointerData(osgGA::GUIEventAdapter& source_event, osgGA::GUIEventAdapter& dest_event);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -528,7 +528,6 @@ protected:
|
||||
osg::Object(), osgGA::GUIEventHandler(), osg::Drawable::CullCallback(), _fullscreen(false) {}
|
||||
|
||||
bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
|
||||
bool computeIntersections(osgViewer::View* view, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff) const;
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user