+ // Covert the screen coordinates to viewport coordinates in the
+ // range [0:1], then transform to OpenGL "post projection" coords
+ // in [-1:1]. Remember the difference in Y direction!
+ float vx = (x + 0.5 - _lastViewport[0]) / _lastViewport[2];
+ float vy = (y + 0.5 - _lastViewport[1]) / _lastViewport[3];
+ vx = 2*vx - 1;
+ vy = 1 - 2*vy;
+
+ // Make two vectors in post-projection coordinates at the given
+ // screen, one in the near field and one in the far field.
+ osg::Vec3 a, b;
+ a[0] = b[0] = vx;
+ a[1] = b[1] = vy;
+ a[2] = 0.75; // "Near" Z value
+ b[2] = -0.75; // "Far" Z value
+
+ // Run both vectors "backwards" through the OpenGL matrix
+ // transformation. Remember to w-normalize the vectors!
+ osg::Matrix m = _lastModelview*_lastProjection;
+ m = osg::Matrix::inverse(m);
+
+ a = m.preMult(a);
+ b = m.preMult(b);
+
+ // And find their intersection on the z=0 plane. The resulting X
+ // and Y coordinates are the hit location in panel coordinates.
+ float dxdz = (b[0] - a[0]) / (b[2] - a[2]);
+ float dydz = (b[1] - a[1]) / (b[2] - a[2]);
+ int panelX = (int)(a[0] - a[2]*dxdz + 0.5);
+ int panelY = (int)(a[1] - a[2]*dydz + 0.5);
+
+ return _panel->doLocalMouseAction(button, updown, panelX, panelY);