From bbb8b066eb295ba782cf1486f9db2f1d71d53f3e Mon Sep 17 00:00:00 2001 From: curt <curt> Date: Mon, 12 Dec 2005 21:15:20 +0000 Subject: [PATCH] =?UTF-8?q?Mathias=20Fr=C3=B6hlich:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Computes the pick direction and starting point. This is code that translates a screen coordinate into a vector in the FlightGear world (between the eye and the on-screen coordinate.) Armed with this vector in FG world coordinates, you could call a scenery intersection routine and lookup the lon/lat/elev of the point in the world that was clicked on. --- src/Main/renderer.cxx | 45 +++++++++++++++++++++++++++++++++++++++++++ src/Main/renderer.hxx | 6 ++++++ 2 files changed, 51 insertions(+) diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index 5b704cc52..0e25a7169 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -920,5 +920,50 @@ void FGRenderer::setNearFar( float n, float f ) { fgHackFrustum(); } +bool FGRenderer::getPickInfo( sgdVec3 pt, sgdVec3 dir, unsigned x, unsigned y ) +{ + // Get the matrices involved in the transform from global to screen + // coordinates. + sgMat4 pm; + ssgGetProjectionMatrix(pm); + sgMat4 mv; + ssgGetModelviewMatrix(mv); + + // Compose ... + sgMat4 m; + sgMultMat4(m, pm, mv); + // ... and invert + sgInvertMat4(m); + + // Get the width and height of the display to be able to normalize the + // mouse coordinate + float width = fgGetInt("/sim/startup/xsize"); + float height = fgGetInt("/sim/startup/ysize"); + + // Compute some coordinates of in the line from the eyepoint to the + // mouse click coodinates. + // First build the normalized projection coordinates + sgVec4 normPt; + sgSetVec4(normPt, (2*x - width)/width, -(2*y - height)/height, 1, 1); + // Transform them into the real world + sgVec4 worldPt; + sgXformPnt4(worldPt, normPt, m); + if (worldPt[3] == 0) + return false; + sgScaleVec3(worldPt, 1/worldPt[3]); + + // Now build a direction from the point + FGViewer* view = globals->get_current_view(); + sgVec4 fDir; + sgSubVec3(fDir, worldPt, view->get_view_pos()); + sgdSetVec3(dir, fDir); + sgdNormalizeVec3(dir); + + // Copy the start point + sgdCopyVec3(pt, view->get_absolute_view_pos()); + + return true; +} // end of renderer.cxx + diff --git a/src/Main/renderer.hxx b/src/Main/renderer.hxx index ed9fe6df2..de33b114a 100644 --- a/src/Main/renderer.hxx +++ b/src/Main/renderer.hxx @@ -44,6 +44,12 @@ public: * clip planes rather than calling the ssg routine directly */ static void setNearFar( float n, float f ); + + /** Get the pick start point and direction in global coordinates. + * The inputs are expected to be the x and y coordinates of the + * screen point relative to the window. + */ + static bool getPickInfo( sgdVec3 p, sgdVec3 d, unsigned x, unsigned y ); }; #endif